route is not working in node.js - javascript

campground data i m working on this web app from a course where i m using mongodb ,the database is created (named as "campit") and collection is named as campground(but mongo has named it campgrounds as usual) .the collection consist of name and image. a route (namely "/create") is not working,
by going to url "localhost:3000/create.ejs" its showing Cannot GET /index.ejs
here is my code,this is app.js file
var express=require("express");
var app=express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({extended:true}));
var mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/campit");
var campgroundSchema=new mongoose.Schema({
name:String,
image:String
});
app.get("/create",function(req,res){
campground.find({},function(err,campground){
if(err){
console.log(err)
}
else{
console.log("successfully shown");
res.render("index.ejs",{campgrounds:campground})
}
});
app.listen("3000",function(){
console.log("listening from server 3000");
});
this is index.ejs file,which is supposed to show
<div class="container">
<div class="row no-gutters">
<% campgrounds.forEach(function(camp){ %>
<div class="col col-lg-4 img-thumbnail">
<img class="but" height="75%" width="100%" src="<%=camp.image%>" alt="image">
<div class="text-center">
<h6><%= camp.name %> </h6>
<button class="btn btn-outline-info " type="button" name="more info"> more info</button>
</div>
</div>
<% }); %>
</div>
</div>
EDIT
when i m going to /create route it shows that campgrounds.forEach is not a function error......whole code is same, something is wrong with rendering variable..... and i m sure that campgrounds contain data.
EDIT CLOSE
any kind of help will be highly appriciated.
thank you.....

You are hitting wrong url. As you can see in you code.
app.get("/create", function(req,res){
campground.find({},function(err,campground){
if(err){
console.log(err)
}
else{
console.log("successfully shown");
res.render("index.ejs",{campgrounds:campground})
}
}
});
Route you should be using is /create and not /create.ejs. index.ejs is the template rendered when you visit /create route

Use this url localhost:3000/create instead of localhost:3000/create.ejs :)
In your Javascript file, you wrote app.get('/create'). create.ejs its just the name of your template. The path of your route and the name of your template doesn't need to be the same.

Try using:
var router = express.Router();
router.route('/create')
.get(function(req,res){
campground.find({},function(err,campground){
if(err){
console.log(err)
}
else{
console.log("successfully shown");
res.render("index.ejs",{campgrounds:campground})
}
});
app.use('', router);

You forget to set view engine, use code below after app.use(bodyParser.urlencoded({extended:true}));
USE IT
app.set("view engine", "ejs");

Related

Express.js req.body.variableName returning undefined

I'm working on a website using Node.js with Express and EJS as the templating engine, and I'm having trouble getting data from the form on the site. Here is my code:
app.js
//app.js
'use strict';
var debug = require('debug');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var session = require('express-session');
var app = express();
const { getSearchPage, search } = require('./routes/search');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
app.get('/search', getSearchPage);
app.post('/search', search);
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
search.js
//search.js (in routes folder)
module.exports = {
getSearchPage: (req, res) => {
res.render('search.ejs');
},
search: (req, res) => {
var artist = req.body.searchArtist;
var song = req.body.searchSong;
var genre = req.body.searchGenre;
var decade = req.body.searchDecade;
console.log("The variables from the page: ", req.body, artist, song, genre, decade); //logs "{} undefined undefined undefined undefined"
if (song) {
//query the database and return some results
}
res.render('search.ejs', { outputArray: outputArray });
}
}
search.ejs
<!DOCTYPE html>
<html lang="en" and dir="Itr">
<head>
<meta charset="utf-8">
<title>Home</title>
<!--link rel="stylesheet" href="css/search.css"-->
<script src="https://kit.fontawesome.com/9b28d88510.js" crossorigin="anonymous"></script>
</head>
<body>
<form method="post" enctype="multipart/form-data">
<div class="search-box">
<input class="search-txt" type="text" name="searchSong" placeholder="Type to search">
<a class="search-btn" href="#">
<i class="fas fa-search"></i>
</a>
</div>
<div class="search-box2">
<input class="search-txt2" type="text" name="searchArtist" placeholder="Type to search">
<a class="search-btn2" href="#">
<i class="fas fa-search"></i>
</a>
</div>
<div class="search-box3">
<input class="search-txt3" type="text" name="searchGenre" placeholder="Type to search">
<a class="search-btn3" href="#">
<i class="fas fa-search"></i>
</a>
</div>
<div class="search-box4">
<input class="search-txt4" type="text" name="searchDecade" placeholder="Type to search">
<a class="search-btn4" href="#">
<i class="fas fa-search"></i>
</a>
</div>
<button type="submit">Search!</button>
</form>
<% if(typeof outputArray != 'undefined'){%>
<ul>
<% outputArray.forEach(function(song) { %>
<li><%= song %></li>
<% }); %>
<% } %>
</ul>
</body>
</html>
I've tried setting urlencoded({extended: }) to true and to false, I've tried changing the form type to application/x-www-form-urlencoded, I've tried changing the post to a get, I've made sure I have body-parser installed, I've tried putting the routes before the server declaration. I've read through most of the pages here on the same issue, but none of those fixes have worked for me. Even more confusingly, I'm following almost exactly with this tutorial, and I don't think I've missed anything that they did. This is my first time ever using Node.js/Express.js/EJS, but I've read through countless forum posts on this exact topic and I still can't figure out where it's going wrong.
You have body parsers capable of handling requests formatted as JSON or URL Encoded data.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
… but your form isn't using either of those:
<form method="post" enctype="multipart/form-data">
You don't have any file inputs, so there is no reason to use multipart/form-data (which is more bandwidth intensive that the default URL encoded data).
Remove the enctype attribute.
If you wanted to support file inputs then you would need to support multipart/form-data.
One way to do that is to use the express-fileupload module, which the tutorial you linked to recommends but you didn't use.

How to use `GET` and `POST` parameters inside Static Assets in ExpressJS

When using PHP to render pages that make use of the request parameters of GET and POST, we can do something similar to:
<p>Hello, <?php echo $_GET["name"]; ?>!</p>
And when we request the file like: /?name=Mike, we get the following output:
<p>Hello, Mike!</p>
Using Node JS and Express JS, I serve static files using the following universal code:
app.get('/user/:name', function(req, res) {
res.render('user.html', {
UserName: req.params.name
});
});
Here, in the user.html, I would like to use something like:
<p>Hello, <? document.write(UserName); ?>!</p>
<p>Hello, <? document.write(req.params.name); ?>!</p>
Something, that switches into the server side and then gets the params and displays here. Is there any way to do it using the static files, where user.html is a static file?
Yo can do it by using RegularExperssion in Query String
the request URL would be like this "http://servername/Profile?Name=Amir"
app.get(new RegExp("Profile(\\.(?:htm|html))?(\\?.*)?$"), function (req, res) {
var queryData = url.parse(req.url, true).query;
var Name = queryData.Name;
console.log(Name)
res.render(__dirname + "/Pages/AppView.ejs", {
username: Name ,
})
})
in ejs template would be like :
<h1> Welcome , <%= username %> </h1>

Braintree payment nodeJS paymentMethodNonce

Good day everyone,
I am trying to workout Braintree payment system using NodeJs. The view is rendered using HandleBars (HBS), and then upon submision the payment is processed in payment.js. My issue is in the view, the braintree payment by credit card or by paypal container does not display. I am not sure if its because HBS does not support script tags, but i need to grab the paymentMethodNonce code and then inject into payment.js file
Below is the view file
payment.hbs file
<h1> This package will cost you 7$ </h1>
<h3> You can pay via credit card or using paypal </h3>
<form action="/pickup/payment/process" method="post">
<fieldset>
<div class="pure-g">
</div>
<br>
<div id="checkout"></div>
<b
utton class="btn-submit" type="submit">Pay now</button>
</fieldset>
</form>
</div>
<br>
<br><br>
<script src="https://js.braintreegateway.com/js/braintree-2.27.0.min.js"></script>
<script>
braintree.setup('<%- clientToken %>', 'dropin', {
container: 'checkout'
});
</script>
<a href="https://www.braintreegateway.com/merchants/ID/verified" target="_blank">
<img src="https://s3.amazonaws.com/braintree-badges/braintree-badge-wide-dark.png" width="280px" height ="44px" border="0"/>
</a>
payment.js file
var express = require('express');
var router = express.Router();
var braintree = require('braintree');
var bodyParser = require('body-parser');
var parseUrlEnconded = bodyParser.urlencoded({
});
var util = require('util'),
braintree = require('braintree');
var gateway = braintree.connect({
environment: braintree.Environment.Sandbox,
merchantId: '[...]',
publicKey: '[...]',
privateKey: '[...]'
});
gateway.transaction.sale({
amount: '7.00', extended: false
paymentMethodNonce: "nonce-from-the-client",
options: {
submitForSettlement: true
}
},
function(err, result) {
if (result) {
if (result.success) {
console.log("Transaction ID: " + result.transaction.id)
} else {
console.log(result.message)
}
} else {
console.log(err)
}
});
Any help will be appreciated. For any clarification, let me know.
Dropin UI will load only when clientToken is provided. You must add new method at payment.js backend to generate client token. Call this method from your frontend and pass clientToken.
btClientToken:function(req,res){
gateway.clientToken.generate({}, function (err, response) {
if(err){
res.status(400).json({'message':err});
}else{
res.status(200).json({clientToken: response.clientToken});
}
});
}

How to get value from .ejs to javascript file

I have a .ejs file, which is actually a drop down form, that fills data using sqlite3 database. Now what i want to do is, when i select a value from dropdown, i want to send it back to my javascript file, where i'd save it to database.
Normally this wasn't hard on a select statement which i made on my own, but as this select statement gets filled from javascript, the value that sends back is undefined, don't know why.
To sum up on example:
I have a user that is logged in, and has option to save a workout on a dropdown.
Workout table
ID: 5
Name: Biceps
Result
Exercise
ID:1
Name: Biceps
Workout-ID: 5
My code
Javascript to .ejs
var Workout = bookshelf.Model.extend({
tableName: 'workout'
});
var Exercise = bookshelf.Model.extend({
tableName: 'exercise',
workout: function()
{
return this.hasMany(Workout)
}
});
router.get('/', function (req, res) {
new Vaje().fetchAll().then(function (workout) {
res.render('Exercise', { workout: workout });
}).catch(function (error) {
console.log(error);
});
});
This sends all of the data from workout table into select form on .ejs
.ejs file
<h2>Select workout</h2>
<select>
<% workout.forEach(function(w) { %>
<option id=""
<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<form method="post">
<input type="submit" value="Add workout" />
</form>
javascript file
This file should now get selected value and save it to database...
router.post('/', function (req, res) {
var new_workout = req.body;
console.log("Workout: " + JSON.stringify(new_workout));
new Exercise().save(new_workout);
});
Result from console
I have no idea why the value is undefined/empty, but i would sure as hell like to find out.
Any help will be much appreciated!
UPDATE
UPDATE2
SOLUTION
router.post('/', function (req, res) {
new Vaje({ 'id': parseInt(req.body.naziv) })
.fetch()
.then(function (new_workout) {
if (new_workout != null)
new Trening().save({
vaje_id: new_workout.get("id"),
naziv: new_workout.get("naziv")
});
});
});
The issue is your ejs file. You have Select out of your Form.
<h2>Select workout</h2>
<form method="post">
<select name="workout">
<% workout.forEach(function(w) { %>
<option value="<%=w.attributes.id%>">
<%= w.attributes.name %>
</option>
<% }); %>
</select>
<br></br>
<input type="submit" value="Add workout" />
</form>
Edit 1
Did you add to your application (for express 3).
app.use(express.bodyParser());
Its required to process post body.
Edit 2 - solution for Express v.4
first you need to install additional package
npm install body-parser --save
later edit your app:
var express = require('express'); // <- this is your code
var bodyParser = require('body-parser');
var app = express(); // <- this is your code
app.use(bodyParser.urlencoded({ extended: false }));
// and now app listen
app.listen(8888); // <- your port here
Edit 3
How to get Name & id. It will be something like this.
router.post('/', function (req, res) {
new Workout({'id': parseInt(req.body.workout)})
.fetch()
.then(function(new_workout) {
if(new_workout != null)
new Exercise().save({
vaje_id: new_workout.get("id"),
name: new_workout.get("name")
});
});
});

Mongoose $push from HTML Form not working

Can anyone tell me what am I doing wrong.
My HTML Form:
<form action="/user/:id" method="put">
<div class="form-group">
<label>Miles</label>
<input type="text" class="form-control" name="miles">
</div>
<button type="submit" class="btn btn-warning btn-lg">Login</button>
</form>
My Express Route:
app.put('/user/:id', function(req, res) {
User.findById(req.body.params.id, function(err, user) {
if (err)
res.send(err);
console.log(user.id);
User.findByIdAndUpdate(
user.id,
{$push: {"milesLog": {miles: req.body.miles}}},
{safe: true, upsert: true},
function(err, model) {
console.log(err);
},
res.json(user)
);
Posting from my HTML form I get the following Error:
Cannot GET /user?miles=66&activity=asdasd
But When I test this through POSTMAN it works:
What am I doing wrong. Why doesn't it work from my HTML Form?
The route doesn't match, you have this URL
/user?miles=66&activity=asdasd
and then this route
app.put('/user/:id', ....
that route is looking for something like this
/user/66
it doesn't look for querystrings, that would be
app.put('/user', function(req, res) {
var miles = req.query.miles;
var activity = req.query.activity;
and unless you have a really good reason for using PUT request, you should change that to use GET instead.
Also, <form action="/user/:id" ... isn't a valid URL, you can't have colons in the URL, and you seem to have misunderstood a little, the :id in your route matches anything, as long as it's a valid route, so it will match
/user/frank
/user/77
/user/something?querystring
etc. and then you can access that inside the route
app.get('/user/:id', function(req, res) {
var user = req.params.id; // returns "frank" etc
There is no "PUT" verb in html forms, while you are implementing it like this:
<form action="/user/:id" method="put">
You have to use method="POST" in html form and change your route to:
app.post('/user/:id')
It's not a bad thing to use such method.
However if you are developing a front-end application it's common to use XMLHttpRequest object which has "PUT" verb, and your route will work just fine.

Categories

Resources