Express js flow behavior - javascript

I need to understand how flow works in an Express app using Routes,
I have These Routes
app.use(require('./routes/reportsRouter'));
app.use(require('./routes/crewsRouter'));
app.use(require('./routes/api'));
app.use(require('./routes/filesRouter'));
Now in ./routes/crewsRouter I have th following Code
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
var url = req.url;
//..... Edit URL if Contains // empty parm
// crews//today; correct Url crews/all/today
// this give me a list of all jobs for all crews for today.
console.log("CrewsRouter: ", req.method + ".( " + url + " )");
next();
});
router.get('/crews', function(req, res) {
if (!req.params.key) { next(); }
res.render('crewsView',{
pageTitle:'All-Crews',
pageID:'crews',
crewInfo: {"aka": "all"},
reqOptions: ''
});
});
router.get('/crews/:leadId?/:options?', function(req, res) {....}
module.exports = router;
and in reportsRouter.js
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
// log each request to the console
console.log("ReportsRouter: ", req.method + ".( " + req.url + " )");
// continue doing what we were doing and go to the route
next();
});
router.get('/reports', function(req, res) {
//var data = req.app.get('appData')
res.render('reportsView',{
pageTitle:'Reports',
pageID:'reports'
});
});
module.exports = router;
The behavior I'm having is no matter what route I request
both of the route.use is running. Is this normal and what can i do to stop this behavior.

let crewsRouter = require('routes/crewsRouter');
...
app.use('/crews', crewsRouter);
app.use('/reports', reportsRouter);
# crews
...
router.get('/', function(req, res) {
... # this used to be your '/crews' handler
}
# reports
...
router.get('/', function(req, res) {
... # this used to be your '/reports' handler
}

You should probably be doing something like this:
app.use('/reports', require('./routes/reportsRouter'));
app.use('/crews', require('./routes/crewsRouter'));
app.use('/api', require('./routes/api'));
app.use('/files', require('./routes/filesRouter'));
And then in your reportsRouter:
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
// log each request to the console
console.log("ReportsRouter: ", req.method + ".( " + req.url + " )");
// continue doing what we were doing and go to the route
next();
});
router.get('/', function(req, res) {
//var data = req.app.get('appData')
res.render('reportsView',{
pageTitle:'Reports',
pageID:'reports'
});
});
module.exports = router;
And your crewsRouter:
var express = require('express');
var router = express.Router();
router.use(function(req, res, next) {
var url = req.url;
//..... Edit URL if Contains // empty parm
// crews//today; correct Url crews/all/today
// this give me a list of all jobs for all crews for today.
console.log("CrewsRouter: ", req.method + ".( " + url + " )");
next();
});
router.get('/', function(req, res) {
if (!req.params.key) { return next(); }
res.render('crewsView',{
pageTitle:'All-Crews',
pageID:'crews',
crewInfo: {"aka": "all"},
reqOptions: ''
});
});
router.get('/:leadId?/:options?', function(req, res) {....});
module.exports = router;

Related

Additional Route

I want to add a second route to a /privacy page, but it is not working. I get "Cannot GET /privacy.html" error. Any suggestions??
This code does not respond with the privacy.html content
app.get('/privacy', function(req, res) {
res.sendFile(__dirname + "/privacy.html");
});
Here is my app.js code
//jshuint esversion: 6
const express = require("express");
const bodyParser = require("body-parser");
const request = require("request");
const https = require("https");
const app = express();
app.use(express.static("public"));
app.use(bodyParser.urlencoded({extended: true}));
app.get('/', function(req, res) {
res.sendFile(__dirname + "/signup.html");
});
app.get('/privacy', function(req, res) {
res.sendFile(__dirname + "/privacy.html");
});
app.post("/", function(req, res) {
const firstName = req.body.firstName;
const lastName = req.body.lastName;
const emailAddress = req.body.emailAddress;
const data = {
members: [
{
email_address: emailAddress,
status: "subscribed",
merge_fields: {
FNAME: firstName,
LNAME: lastName
}
}
]
};
const jsonData = JSON.stringify(data);
const url = "https://us.api.mailchimp.com/3.0/lists/bb80b745a8"
const options = {
method: "POST",
auth: "meshiaR:93d648-u"
};
const request = https.request(url, options, function(response) {
if (response.statusCode === 200) {
res.sendFile(__dirname + "/success.html");
} else {
res.sendFile(__dirname + "/failure.html");
}
response.on("data", function(data){
console.log(JSON.parse(data));
});
});
request.write(jsonData);
request.end();
});
// app.post("/privacy", function(req, res){
// res.sendFile(__dirname + "/privacy.html");
// });
app.post("/failure", function(req, res) {
res.redirect("/");
});
app.listen(process.env.PORT || 3000, function(){
console.log("Server is now running on port 3000");
});
This is how I achieve this kind of tasks.
var path = require('path');
app.get('/privacy', function(req, res) {
res.sendFile(path.join(__dirname + '/privacy.html'));
});
BTW, check your privacy.html is available in correct path.

node.js Cannot read property 'collection' of undefined routes\index.js:6:11

I am a begginer at node.js and trying to build a basic todo list but keep getting the error:
Cannot read property 'collection' of undefined.
Can someone please explain what im doing wrong and how to I can get my get post requests working?
Thanks for the help !
routes/index.js
var express = require('express');
var router = express.Router();
var ObjectId = require('mongodb').ObjectId
// Get Homepage
router.get('/', ensureAuthenticated, function(req, res){
req.db.collection('Todo').find().sort({"_id": -1}).toArray(function(err, result) {
//if (err) return console.log(err)
if (err) {
req.flash('error', err)
res.render('index', {
title: 'User List',
data: ''
})
} else {
// render to views/user/list.ejs template file
res.render('index', {
title: 'User List',
data: 'ldld'
})
}
})
})
function ensureAuthenticated(req, res, next){
if(req.isAuthenticated()){
return next();
} else {
//req.flash('error_msg','You are not logged in');
res.redirect('/users/login');
}
}
module.exports = router;
routes/Todo.js
// list dependencies
var express = require('express');
var router = express.Router();
// add db & model dependencies
var mongoose = require('mongoose');
var Todo = require('../models/Todo');
// interpret GET /products - show product listing */
// GET intepret GET /products/edit/:id - show single product edit form */
router.get('/Todo/edit/:id', function (req, res, next) {
//store the id from the url in a variable
var id = req.params.id;
var user_id = req.cookies ?
req.cookies.user_id : undefined;
//use the product model to look up the product with this id
Todo.findById(id,user_id, function (err, product) {
if (err) {
res.send('Product ' + id + ' not found');
}
else {
res.render('edit', { Todo: Todo });
}
});
});
// POST /products/edit/:id - update selected product */
router.post('/Todo/edit/:id', function (req, res, next) {
var id = req.body.id;
var Todo = {
_id: req.body.id,
content: req.body.content,
todos : todos,
updated_at : Date.now()
};
Todo.update({ _id: id}, content, function(err) {
if (err) {
res.send('Product ' + req.body.id + ' not updated. Error: ' + err);
}
else {
res.statusCode = 302;
res.setHeader('Location', 'http://' + req.headers['host'] + '/Todo');
res.end();
}
});
});
// GET /products/add - show product input form
router.get('/Todo/create', function (req, res, next) {
res.render('add');
});
// POST /products/add - save new product
router.post('/Todo/create', function (req, res, next) {
// use the Product model to insert a new product
Todo.create({
content: req.body.content,
user_id:req.cookies.user_id,
updated_at : Date.now()
}, function (err,Todo) {
if (err) {
console.log(err);
res.render('error', { error: err }) ;
}
else {
console.log('Product saved ' + Todo);
res.render('added', {Todo: Todo.content });
}
});
});
// API GET products request handler
router.get('/api/Todo', function (req, res, next) {
Todo.find(function (err, products) {
if (err) {
res.send(err);
}
else {
res.send(Todo);
}
});
});
/* GET product delete request - : indicates id is a variable */
router.get('/Todo/delete/:id', function (req, res, next) {
//store the id from the url into a variable
var id = req.params.id;
//use our product model to delete
Todo.remove({ _id: id }, function (err,Todo) {
if (err) {
res.send('Product ' + id + ' not found');
}
else {
res.statusCode = 302;
res.setHeader('Location', 'http://' + req.headers['host'] + '/Todo');
res.end();
}
});
});
// make controller public
module.exports = router;
views/index.handelbars
<h2 class="page-header">Dashboard</h2>
<p> Hello {{user.name}}
<p>Welcome to your dashboard</p>
<% layout( 'layout' ) -%>
<h1 id="page-title">{{ title }}</h1>
<div id="list">
<form action="/create" method="post" accept-charset="utf-8">
<div class="item-new">
<input class="input" type="text" name="content" />
</div>
</form>
{{#each todo}}
<div class="item">
<a class="update-link" href="/edit/{{#todo._id }}" title="Update this todo item">{{todo.content}}</a>
<a class="del-btn" href="/destroy/{{ #todo._id }}>" title="Delete this todo item">Delete</a>
</div>
{{/each }}
app.js
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');
var Todo = require('./routes/Todo');
// 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');
// BodyParser 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
app.use(session({
secret: 'secret',
saveUninitialized: true,
resave: true
}));
// Passport init
app.use(passport.initialize());
app.use(passport.session());
// Express Validator
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
app.use(flash());
// Global Vars
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);
app.use('/Todo', Todo);
// Set Port
app.set('port', (process.env.PORT || 3000));
app.listen(app.get('port'), function(){
console.log('Server started on port '+app.get('port'));
});
Add the following to your app.js, right after var app = express();
app.use(function (req, res, next) {
req.db = db;
next();
});
This will create a reference to your mongoose connection in all the incoming requests, accessible via req.db.

GET /dishes 500 4.732 ms - - Error: Can't set headers after they are sent

I am new to Node.js,and so far I have managed to install Express. Now I have three js files,that handle CRUD requests to a localserver.
ie.
localhost:3000/dishes
localhost:3000/promotions
etc. However, when I am doing a simple get request in postman,I get this error.
GET /dishes 500 8.883 ms - -
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
I am going to show you my files.
dishRouter.js
//exporing the functionality
module.exports = function (dishRouter, bp) {
dishRouter.use(bp.json()); //using body parser for parsing json from body
content
//code for url '/'
dishRouter.route('/').all(function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send all the dishes to you!');
})
//setting up code for post request
.post(function (req, res, next) {
res.end('Will add the dish: ' + req.body.name + ' with details: ' +
req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting all dishes');
});
//code for url with specific ids
dishRouter.route('/:dishId')
.all(function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send details of the dish: ' + req.params.dishId + ' to you!');
})
//setting up code for put request
.put(function (req, res, next) {
res.write('Updating the dish: ' + req.params.dishId + '\n');
res.end('Will update the dish: ' + req.body.name +
' with details: ' + req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting dish: ' + req.params.dishId);
});
};
promoRouter.js
//exporting the functionality
module.exports = function (promoRouter, bp) {
promoRouter.use(bp.json()); //using body parser for parsing json
from body content
//code for url '/'
promoRouter.route('/').all(function (req, res, next) {
res.writeHead(200, { //writing header
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send all the promotions to you!');
})
//setting up code for post request
.post(function (req, res, next) {
res.end('Will add the promotion: ' + req.body.name + ' with
details: ' + req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting all promotions');
});
//code for url with specific ids
promoRouter.route('/:promoId')
.all(function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send details of the promotion: ' +
req.params.promoId + ' to you!');
})
//setting up code for put request
.put(function (req, res, next) {
res.write('Updating the promotion: ' + req.params.promoId + '\n');
res.end('Will update the promotion: ' + req.body.name +
' with details: ' + req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting promotion: ' + req.params.promoId);
});
};
leaderRouter.js
//exporing the functionality
module.exports = function (leaderRouter, bp) {
leaderRouter.use(bp.json()); //using body parser for parsing json from body
content
//code for url '/'
leaderRouter.route('/').all(function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send all the leaders to you!');
})
//setting up code for post request
.post(function (req, res, next) {
res.end('Will add the leader: ' + req.body.name + ' with details: '
+ req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting all leaders');
});
//code for url with specific ids
leaderRouter.route('/:leaderId')
.all(function (req, res, next) {
res.writeHead(200, {
'Content-Type': 'text/plain'
});
next();
})
//setting up code for get request
.get(function (req, res, next) {
res.end('Will send details of the leader: ' + req.params.leaderId + ' to you!');
})
//setting up code for put request
.put(function (req, res, next) {
res.write('Updating the leader: ' + req.params.leaderId + '\n');
res.end('Will update the leader: ' + req.body.name +
' with details: ' + req.body.description);
})
//setting up code for delete request
.delete(function (req, res, next) {
res.end('Deleting leader: ' + req.params.leaderId);
});
};
server.js
var express = require('express');
var morgan = require('morgan');
var port = 3000;
var hostname = 'localhost';
var app = express();
app.use(morgan('dev'));
var dishRouter = require('./dishRouter');
app.use('/dishes',dishRouter.exports);
var leaderRouter = require('./leaderRouter');
app.use('/leadership', leaderRouter.router);
var promoRouter = require('./promoRouter');
app.use('/promotions', promoRouter.router);
app.use(express.static(__dirname + '/public'));
app.listen(port, hostname, function () {
console.log(`Server running at http://${hostname}:${port}/`);
});
The above 4 files are inside the routes folder. And finally,I have app.js.
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 routes = require('./routes/index');
var users = require('./routes/users');
var dishRouter = require('./routes/dishRouter');
var promoRouter = require('./routes/promoRouter');
var leaderRouter = require('./routes/leaderRouter');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', routes);
app.use('/users', users);
app.use('/dishes',dishRouter);
app.use('/promotions',promoRouter);
app.use('/leadership',leaderRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
module.exports = app;
Any ideas why I am getting this error? Please advice.
Thanks,
Theo.

Express routes returning 404s

I have a couple of simple routes that I have misconfigured and not sure why.
app.js:
//app setup
var http = require('http');
var bodyParser = require('body-parser');
var express = require('express');
var routes = require('./routes');
var agent = require('./routes/agent');
var config = require('./config');
var app = express();
app.server = http.createServer(app);
app.use(bodyParser.json({
limit : config.bodyLimit
}));
app.use(bodyParser.urlencoded({
extended : true
}));
app.use('/v1', routes);
app.use('/v1/agent', agent);
app.server.listen(config.port);
console.log('API listening on port ' + app.server.address().port);
module.exports = app;
This returns responses on the /v1/ route (index.js):
'use strict';
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {
res.status(403).json({
message: 'Invalid request.'
});
});
module.exports = router;
in the agent route, I have a POST handler that is being handled correctly at /v1/agent/login. But while a GET routed at /v1/agent/ works, a GET routed to /v1/agent/123 returns a 404:
'use strict';
var agentController = require('../controller/agent.js');
var express = require('express');
var router = express.Router();
function handleError(objError, res) {
res.status(500).json({ errorMessage : objError.message });
}
router.get('/', function (req, res) {
res.status(200).json({
message: 'OK' // works fine
});
});
router.get('/:id'), function (req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
};
router.post('/login', function (req, res) {
var agentNum, password;
// works fine
});
router.post('/pwr', function (req, res) {
//also works fine
});
module.exports = router;
My understanding is that the app.use method should redirect the route and any GET requests appended to that route to the one I specified (agent), so why is it that the one with params fails while the root one succeeds?
Thank you
You're not passing the callback correctly.
router.get('/:id')
router.get('/:id', function(req, res) {
var agentNum = req.params.id;
res.send(req.params); // 404 here
try {
//res.status(200).json({ message: 'hello agent.'});
} catch (err) {
// handleError(err, res);
}
});

Express.js multilanguage with i18n-node

How to call controller with express.js routing?
app.get('*', function(req, res, next) {
var regExp = /^\/([a-z]{2})(\/|$)/gi,
exec = regExp.exec(req.url);
exec = exec != null ? exec[1] : undefined;
if(exec == undefined) {
// add language prefix to link
}
else {
i18n.setLocale(exec);
// add language prefix to link
}
next();
});
If I open the page /about I need to get url like this: http://example.com/en/about. How I can do it and how to display call 'about' controller?
app.get('/about', function(req, res) {
console.log('Here is about');
res.send('Hello, World');
});
Not suitable: app.get('(en|de|ru)/about', ...)
Thanks in advance.
You could do something like
app.get('/:language/about', function(req, res) {
var language = req.params.language;
i18n.setLocale(language);
});
For multiple routes you could maybe do this
controllers.js
module.exports = {
about: function(req, res) {
res.send('about');
}
}
app.js
var controllers = require('./controllers');
app.all('/:language/:controller', function(req, res) {
i18n.setLocale(req.params.language);
controllers[req.params.controller](req, res);
});
The following works for me very well, so the language code can be optional:
var i18n = require('i18n');
server.use(express.static(__dirname + '/client/www'));
server.use('/en', express.static(__dirname + '/client/www'));
server.use('/zh', express.static(__dirname + '/client/www'));
function regexPath(p) {
return new RegExp('(?:/(en|zh))?' + p, 'i');
}
server.use(i18n.init);
server.all('*', function (req, res, next) {
var l = /^\/(en|zh)/i;
if (l.test(req.url)) {
var a = l.exec(req.url);
var local = a[1];
i18n.setLocale(local);
res.setLocale(local);
} else {
i18n.setLocale('zh');
res.setLocale('zh');
}
next();
});
server.get(regexPath('/signin'), function (req, res) {
res.render('sign-in');
});

Categories

Resources