In the below code , I am authenticating username and password user enters with the details from my mongo database . If successful , redirect to /main route (index.ejs) . I am getting error :- callback is not a function .
I am new to nodejs . I can't figure out where and why I am getting this error .
app.js
var express = require('express');
var app = 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 urlencoder = bodyParser.urlencoded({extended : true});
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://<username>: <password>#ds141434.mlab.com:41434/teacherspro'; // using mLab
app.set('view engine' , 'ejs'); // ejs as view engine
var index = require('./routes/index'); // providing routes
var users = require('./routes/users');
app.set('views', path.join(__dirname, 'views'));
app.use(logger('dev'));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/main', index);
app.use('/users', users);
app.get('/login' , function(req,res,next){ // rendering homepage
console.log('\r');
res.render('login'); // rendering login.ejs
console.log('rendered master page!');
next();
});
MongoClient.connect(url , function(err,db){
if (err) return;
app.post('/login' , urlencoder , function(req,res,next){
app.use(bodyParser.json());
var UserName = req.body.UserName;
var Password = req.body.Password;
db.collection('project1').find({ '$and' : [ {"UserName" : UserName} , {"Password" : Password} ]} , {_id : 0}).forEach(function(pes){ // authenticating username and password
if(true)
{
console.log(pes);
res.redirect('/main');
}
});
});
db.close();
next();
});
app.listen(5050);
module.exports = app;
Index.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
MongoClient.connect(url , function(err,db){
if (err) return;
db.collection('project1').find({"UserName" : "karan"} , {_id : 0}).forEach(function(pes){
console.log(pes);
res.render('index', {Name : pes});
});
});
});
module.exports = router;
login.ejs
<form id = 'login' method = POST action = '/login'>
<label for = 'Username'> UserName </label>
<input type = 'text' name = 'UserName' value = ''>
<br />
<label for = 'Password'> Password </label>
<input type = 'password' name = 'Password' value = ''>
<br />
<center> <input type ="submit" value = "submit" /> </center>
<br />
</form>
Post callback has the following form:
app.post(path, callback);
Check the docs. app.post
Just remove urlencoder param.
Related
I am using the express framework with EJS as the view engine. I have some basic routes ('/' & '/users') in the application. I also have a form in my EJS page which I'm using the users to login. Here I have form with action="/login" and method="POST". And I have created a handler function app.post in the app.js to check credentials and redirect to users page.
But when I click submit button of the page express app saying that "/login" not found. Below is the directory structure of the entire app.
menu.ejs:
<form method="POST" action="/login">
<input type="text" name="username" placeholder="Username">
<input type="password" name="password" placeholder="Password">
<input type="submit" name="login" class="login loginmodal-submit" value="Login">
</form>
And the app.js
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require('express-session');
var mysql = require('mysql');
var bodyParser = require('body-parser');
var path = require('path');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var loginRouter = require('./routes/login');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/login', loginRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
//express session
app.use(session({
secret:'secret_key',
resave:true,
saveUninitialized:true
}));
app.use(bodyParser.urlencoded({
extended:true
}));
app.use(bodyParser.json());
mysql
var connection = mysql.createConnection({
host:'localhost',
user:'root',
password:'secret_pw',
database:'my_db'
});
//login authentication
app.post('/login', function(req,res){
var username = req.body.username;
var password = req.body.password;
if(username && password){
connection.query('SELECT username,password FROM logindetails WHERE username = ? AND password = ?',[username,password], function(error,results,fields){
if(results.length > 0){
req.session.loggedin = true;
req.session.username = username;
res.redirect('/users');
} else{
res.send('Incorrect username and password');
}
res.end();
});
}
else{
res.send('Please enter username and password');
res.end();
}
});
module.exports = app;
And the login route is
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', { page:'home', menuId:'home' });
});
module.exports = router;
Omit this code from app.js
app.post('/login', function(req,res){
/....../
});
Then add this to login-router
router.post('/', function(req, res) {
/......../
});
Because your app reach this block below before executing app.post
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
Move the following block below app.post.
Also, you should initialise bodyParser and session before initialising routes.
I'm a newbie so be kind. I've been trying to learn passport via an online tutorial (this one, github here) and as far as I can tell I've recreated the code verbatim but I'm getting an error that the localhost didn't send any data. My full code is here. I'm pasting some code below but I'm honestly unsure which piece of code to post since I don't know where the error is occurring.
Here's the server app:
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var exphbs = require('express-handlebars');
var expressValidator = require('express-validator');
var flash = require('connect-flash');
var session = require('express-session');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mongo = require('mongodb');
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/loginapp');
var db = mongoose.connection;
var routes = require('./routes/index');
var users = require('./routes/users');
//Init app
var app = express();
//View engine
app.set('views', path.join(__dirname, 'views'));
app.engine('handlebars', exphbs({defaultLayout: 'layout'}));
app.set('view engine', 'handlebars');
//body parser middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(cookieParser());
//set static folder
app.use(express.static(path.join(__dirname, 'public')));
//express session middleware
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
//passport init
app.use(passport.initialize());
app.use(passport.session());
//validator middleware-- this code is straight from the validator github page
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split(',')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
//connect flash middleware
app.use(flash());
//global variables for flash messages
app.use(function (req, res, next) {
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
res.locals.user = req.user || null;
next();
});
app.use('/', routes);
app.use('/users', users);
//set port
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function() {
console.log('Server started on port ' + app.get('port'));
});
Here's the form:
<h2 class="page-header">Register</h2>
<form method="post" action="/users/register">
<div class="form-group">
<label>Name</label>
<input type="text" class="form-control" placeholder="Name" name="name">
</div>
<div class="form-group">
<label>Username</label>
<input type="text" class="form-control" placeholder="Username" name="username">
</div>
<div class="form-group">
<label>Email</label>
<input type="email" class="form-control" placeholder="Email" name="email">
</div>
<div class="form-group">
<label>Password</label>
<input type="password" class="form-control" placeholder="Password" name="password">
</div>
<div class="form-group">
<label>Confirm Password</label>
<input type="password" class="form-control" placeholder="Password" name="password2">
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
And here's the user js:
var express = require('express');
var router = express.Router();
//register
router.get('/register', function(req, res) {
res.render('register');
});
//login
router.get('/login', function(req, res) {
res.render('login');
});
//register user
router.post('/register', function(req, res) {
var name = req.body.name;
var email = req.body.email;
var username = req.body.username;
var password = req.body.password;
var password2 = req.body.password2;
});
module.exports = router;
First things first: you are actually not doing anything on the post('/register'..)
You should save your model and return it if successful, something like this:
var schema = new mongoose.Schema({ name: 'string', email: 'string' });
var User = mongoose.model('User', schema);
//register user
router.post('/register', function(req, res) {
var name = req.body.name;
var email = req.body.email;
var user = new User({ name: name, email: email});
user.save(function (err) {
if (err) throw err;
res.send(user);
});
});
Of course you would define your model on a separate folder and import it to where it fits.
I am trying to create a registration form which will pass data to the registration route. However, I am having trouble retrieve the form inputs in registration route. Please advice how to retrieve the form data inside the api.js file. I have tried using POSTMAN to send data to the /api/registration endpoint which did create a user in the database. When I actually use the html form to register, it failed.
HTML
<!DOCTYPE html>
<html>
<body>
<form action="/api/register" enctype="multipart/form-data" method="post">
<input name="email" type="text" placeholder="Email">
<input name="password" type="password" placeholder="Password">
<input name="passwordConf" type="password" placeholder="Confirm Password">
<input type="submit" value="Register">
</form>
</body>
</html>
Index.js
//----setting up modules
const express = require('express');
const hbs = require('hbs');
const path = require('path');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
mongoose.Promise = global.Promise;
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost/test');
//----define port connection on various environmentls
const port = process.env.PORT || 3000;
//----createing express app
var app = express();
// parse incoming requests
app.use(bodyParser.json());
//----use express middle-ware to utitlize public folder
// app.use(express.static(__dirname + 'public'));
app.use('/public', express.static(path.join(__dirname,'public')));
//see the first argument in above line it assigns which directory path is used to access the public file through URL
//----initializing handlebars as express view engine
app.set('view engine', 'hbs');
//----define handlebars partials and helpers
hbs.registerPartials(__dirname + '/views/partials');
//----define helper to get current year
hbs.registerHelper('getDate', ()=>{
return new Date().getFullYear();
});
//----define routes
app.get('/', function (req, res) {
res.render('home.hbs')
})
// include routes
app.use('/api', require('./routes/api'));
app.use('/', require('./routes/page'));
//----connecting to port
app.listen(port,()=>{
console.log(`success connection to port ${port}`);
})
Api.js Route
var express = require('express');
var router = express.Router();
var {User} = require('./../models/user');
var {authenticate} = require('./../middleware/authenticate');
var _ = require('lodash');
var bodyParser = require('body-parser');
var jsonParser = bodyParser.json()
var urlencodedParser = bodyParser.urlencoded({ extended: false })
router.post('/register',function (req, res) {
console.log(req.body);
});
module.exports = router;
pages.js
var express = require('express');
var router = express.Router();
router.get('/register', function (req, res) {
res.render('register.hbs', {title:"REGISTER"} )
})
router.get('/login', function (req, res) {
res.render('login.hbs', {title:"LOGIN"} )
})
module.exports = router;
Here is my recommendation:
Create a file called routes.js and include ALL your routes there and import it.
var express = require('express');
var router = express.Router();
app.get('/', function (req, res) {
res.render('home.hbs')
})
router.get('/api/register', function (req, res) {
res.render('register.hbs', {title:"REGISTER"} )
})
router.post('/api/register',function (req, res) {
//do your post logic here
console.log(req.body);
});
router.get('/login', function (req, res) {
res.render('login.hbs', {title:"LOGIN"} )
})
module.exports = router;
in your Index.js :
//Make sure the route is correct
app.use('/', require('/routes/routes.js'));
Doing this, I expect the error to be solved,
Good luck!
I can't figure out where I missed to add something. I get the following error: Cannot GET /portal/destroybox/5797318673cf3f581163455c when I click on delete or update icons in portal.ejs:
(createbox in portal.ejs works and creates the item and stores it in the db, and then I forEach in the table to show all items with update and delete icons behind each item. Also the // todo test part in server.js is for another part of my app and that works, nothing to do with the portal/box part. I also do not have route in server.js for createbox, but that part works, so why do I need it for destroybox if I need it at all?)
portal.ejs
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Vm</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<% boxes.forEach( function ( box ){ %>
<tr>
<td>
<%= box.box_name %>
</td>
<td>
<%= box.vm %>
</td>
<td>
<a class="fa fa-wrench" aria-hidden="true" href="/portal/editbox/<%= box._id %>" title="Update this box"></a>
</td>
<td>
<a class="fa fa-trash-o" aria-hidden="true" href="/portal/destroybox/<%= box._id %>" title="Destroy this box"></a>
</td>
</tr>
<% }); %>
</tbody>
</table>
<p>
<strong>Add new box to `available boxes`</strong>
<br>
</p>
<form action="/createbox" method="post">
<div class="form-group">
<label>Box name</label>
<input type="text" class="form-control" name="box_name">
</div>
<div class="form-group">
<label>VM</label>
<input type="text" class="form-control" name="vm">
</div>
<div class="form-group">
<label>Description</label>
<input type="text" class="form-control" name="description">
</div>
<button type="submit" class="btn btn-warning btn-lg">Add box</button>
</form>
server.js
// server.js
// set up ======================================================================
// get all the tools we need
// mongoose setup
var db = require('./config/database.js');
require('./app/models/db');
require('./app/models/box');
var express = require('express');
var http = require('http');
var path = require('path');
var engine = require('ejs-locals');
var favicon = require('serve-favicon');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var methodOverride = require('method-override');
var logger = require('morgan');
var errorHandler = require('errorhandler');
var static = require('serve-static');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');
var session = require('express-session');
var routesindex = require('./routes/index');
//var routesbox = require('./routes/boxi');
// configuration ===============================================================
mongoose.connect(db.url); // connect to our database
require('./config/passport')(passport); // pass passport for configuration
// set up our express application
app.engine('ejs', engine);
app.use(logger('dev')); // log every request to the console
app.use(cookieParser()); // read cookies (needed for auth)
app.use(bodyParser()); // get information from html forms
app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(methodOverride());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(session({
secret: 'secretkeykeykeykey'
})); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
// routes ======================================================================
var routes = require('./app/routes/routes')(app, passport); // load our routes and pass in our app and fully configured passport
// todo test
app.use(routesindex.current_user);
app.get('/ind', routesindex.ind);
app.post('/ind/create', routesindex.create);
app.get('/ind/destroy/:id', routesindex.destroy);
app.get('/ind/edit/:id', routesindex.edit);
app.post('/ind/update/:id', routesindex.update);
app.use(static(path.join(__dirname, 'public')));
// launch ======================================================================
app.listen(port);
console.log('The magic happens on port ' + port);
routes.js
// =====================================
// PORTAL ==============================
// =====================================
// show the signup form
app.get('/portal', isLoggedIn, function (req, res) {
var user_id = req.cookies ?
req.cookies.user_id : undefined;
Box.
find({
user_id: user_id
}).
sort('-updated_at').
exec(function (err, boxes) {
if (err) return next(err);
res.render('portal', {
boxes: boxes
});
});
});
app.post('/createbox', isLoggedIn, function (req, res) {
new Box({
user_id: req.cookies.user_id,
box_name: req.body.box_name,
vm: req.body.vm,
description: req.body.description,
updated_at: Date.now()
}).save(function (err, box, count) {
if (err) return next(err);
res.redirect('/portal/');
});
});
app.get('/destroybox/:id', isLoggedIn, function (req, res) {
Box.findById(req.params.id, function (err, box) {
var user_id = req.cookies ?
req.cookies.user_id : undefined;
if (box.user_id !== user_id) {
return utils.forbidden(res);
}
box.remove(function (err, box) {
if (err) return next(err);
res.redirect('/portal/');
});
});
});
app.get('/editbox/:id', isLoggedIn, function (req, res) {
var user_id = req.cookies ?
req.cookies.user_id : undefined;
Box.
find({
user_id: user_id
}).
sort('-updated_at').
exec(function (err, boxes) {
if (err) return next(err);
res.render('editbox', {
title: 'Vagrant Box',
boxes: boxes,
current: req.params.id
});
});
});
app.post('/updatebox/:id', isLoggedIn, function (req, res) {
Box.findById(req.params.id, function (err, box) {
var user_id = req.cookies ?
req.cookies.user_id : undefined;
if (box.user_id !== user_id) {
return utils.forbidden(res);
}
box.box_name = req.body.box_name;
box.vm = req.body.vm;
box.description = req.body.description;
box.updated_at = Date.now();
box.save(function (err, box, count) {
if (err) return next(err);
res.redirect('/portal/');
});
});
});
Because you don't have routes for that as the error states:
app.get('/destroybox/:id'
You can see you have a route from root / to destroybox then :id etc. While you are having a href of:
href="/portal/destroybox/<%= box._id %>"
from root / to portal and then destroybox then the id. Which is no where defined in the config.
Solution is to change the href to:
href="/destroybox/<%= box._id %>"
same goes for other href attributes too.
I am running into an issue where I am trying to run a POST request via Postman and I get a loading request for a long time and then a Could not get any response message. There are no errors that are appearing in terminal. Is it the way I am saving the POST? Specifically looking at my /blog route.
server.js
//Load express
var express = require('express');
var app = express();
var router = express.Router(); // get an instance of the router
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
// configure app to use bodyParser()
// get data from a POST method
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
var port = process.env.PORT || 8080; // set the port
var blogDB = require('./config/blogDB.js');
var Blogpost = require('./app/models/blogModel');
app.set('view engine', 'ejs'); // set ejs as the view engine
app.use(express.static(__dirname + '/public')); // set the public directory
var routes = require('./app/routes');
// use routes.js
app.use(routes);
app.listen(port);
console.log('magic is happening on port' + port);
blogModel.js:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var BlogPostSchema = new Schema({
title : String,
body : String,
date_created : Date
});
module.exports = mongoose.model('Blogpost', BlogPostSchema);
routes.js:
var express = require('express');
var router = express.Router();
var blogDB = require('../config/blogDB.js');
var Blogpost = require('./models/blogModel.js');
//index
router.route('/')
.get(function(req, res) {
var drinks = [
{ name: 'Bloody Mary', drunkness: 3 },
{ name: 'Martini', drunkness: 5 },
{ name: 'Scotch', drunkness: 10}
];
var tagline = "Lets do this.";
res.render('pages/index', {
drinks: drinks,
tagline: tagline
});
});
//blog
router.route('/blog')
.get(function(req, res) {
res.send('This is the blog page');
})
.post(function(req, res) {
var blogpost = new Blogpost(); // create a new instance of a Blogpost model
blogpost.title = req.body.name; // set the blog title
blogpost.body = req.body.body; // set the blog content
blogpost.date_created = Date.now();
blogpost.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Blog created.' });
});
});
//about
router.get('/about', function(req, res) {
res.render('pages/about');
});
module.exports = router;
The issue was that I did not setup a user for my Mongo database. Basically it couldn't gain access to the user/pw to the database that I was using. Once I created a user matching the user/pw I included in my url, then I was able to get a successful post.