Express.js, req.params not being called - express

So i have been racking my brain for quite awhile now trying to figure this out and I'm still having issues.
So i define a route like this:
var home = require('./routes/home');
var app = express();
app.use('/home/:client', home);
And my home.js code looks like this:
var express = require('express');
var router = express.Router();
router.get('/', function(req, res, next) {
res.render('homeview', { title: 'Welcome',
user: username});
});
router.get('/:client', function(req, res, next) {
var theClient = req.params.client;
console.log(theClient)
});
module.exports = router;
And then when i try to go to this URL:
http://www.localhost:3000/home/client
Nothing happens. For some reason it never gets to the second router.get and never logs anything. Anyone notice whats wrong?

Working solution # https://github.com/rmjoia/expressRoutes
app.js
var express = require('express'),
app = express(),
port = process.env.PORT || 3000,
homeRouter = require('./home');
app.use('/home', homeRouter);
app.route('/')
.all(function (request, response, next) {
// Do some plumbing stuff
next();
})
.get(function (request, response, next) {
response.send('OK GET - Hello Stack Overflow');
next();
});
app.listen(port, function (error) {
if (error) {
console.error(error.message);
}
else {
console.info('Server up and running. Listening on port ' + port);
}
})
home.js
var express = require('express');
var homeRouter = express.Router();
var router = (function (router) {
// define the home page route
router.get('/', function (req, res) {
res.send('home route - homepage');
});
// define the about route
router.get('/:client', function (req, res) {
res.send(req.params.client);
});
return homeRouter;
})(homeRouter);
module.exports = router;

Related

Run socket.io from an express route

I have researched on this but nothing seems to satisfy my need. I have an express route connected to a mongodb. Below is part of the code.
const express = require('express');
const socketIo = require("socket.io");
const dbconnect = require("./models");
const handle = require("./handlers");
const routes = require("./routes");
const app = express();
app.use('/messages', routes.messages);
const PORT = 3000;
const server = app.listen(3000, function() {
console.log(`Listening on 3000`);
dbconnect().then(() => {
console.log("MongoDb connected");
});
});
const io = socketIo(server);
io.on('connection', function(client) {
console.log('Connected...');
});
My route looks like this:
const router = require('express').Router();
const handle = require('../handlers/messages');
router.post('/unread_messages', handle.unread_messages);
module.exports = router;
My handler looks like this:
const db = require("../models");
exports.unread_messages = async (req, res, next) => {
try {
const unreadmessages = await db.messages.countDocuments({ $and: [{receiver: req.body.receiver},
{ messageread: false }]});
return res.json({ unreadmessages });
} catch (err) {
return next({ status: 400, message: `Cannot get unread messages ${err}` });
}
};
I would like to add socket to the "/unread_messages" route so that I get an update of the count of unread messages in realtime. How do I do that?

routes in exported router not available in app

I'm trying to export a router 'Accounts' to use in my app. The 'Accounts' router has the paths '/login' (POST), '/register'(POST), 'login' (GET), and '/logout' (POST). In my index app I am using the router with the path '/account'. So the paths should be:
/account/login (POST)
/account/login (GET)
/account/register(POST)
/account/logout (GET)
But when I call these paths they aren't found by the app:
How do I get the paths in the 'accounts.js' router to work in the 'index.js' app?
My file structure is like this:
my account.js file looks like this:
const express = require('express');
const passport = require('passport');
const Account = require('../models/Account');
const Branch = require('../models/Branch')
const router = express.Router({mergeParams: true});
const registerAccount = (req, res, next) => {
//register the account
};
const createUser = (req,res) => {
//create a user in another db
}
router.post('/register',
[registerAccount, createUser]);
router.get('/login', function(req, res) {
res.json(user);
});
router.post('/login', passport.authenticate('local', { successRedirect: '/',
failureRedirect: 'account/login' }));
router.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
});
module.exports=router;
and my index.js looks like this:
// index.js
var express = require("express");
var bodyParser = require("body-parser");
var jwt = require("jwt-simple");
var auth = require("../auth/auth.js")();
var users = require("./users.js");
var cfg = require("../config.js");
const accountController = require('./account');
var app = express();
app.use(bodyParser.json());
app.use(auth.initialize());
app.use('/account',accountController);
app.get("/", function(req, res) {
res.json({
status: "My API is alive!"
});
});
app.post("/token", function(req, res) {
//some token stuff that doesn't matter here
});
module.exports = app;
For starters, you don't pass an array to a router.post(), so change this:
router.post('/register', [registerAccount, createUser]);
to this:
router.post('/register', registerAccount, createUser);
And make sure that registerAccount calls next() when it's done and wants createUser() to get called.
In the doc, for this syntax:
app.post(path, callback [, callback ...])
the brackets in [, callback] mean that parameter is optional. The brackets are not supposed to be used.

Main index route is working, all others are not

Can anyone help me figure out why my express routes arent working please. I have been stuck for days trying to figure this out but I keep getting 404 errors when I got to any of the routes in customer.js
<--------------------main server-------------->
var express = require("express");
var path = require('path');
var app = express();
var indexRouter = require('./routes/index');
var ordersRouter = require('./routes/orders');
var customersRouter = require('./routes/customers');
var productsRouter = require('./routes/products');
app.use('/', indexRouter);
app.use('/customers', customersRouter);
app.use('/orders', ordersRouter);
app.use('/products', productsRouter);
app.listen(80);
module.exports = app;
one of my route files below the only route file works is the index router.
var express = require('express');
var router = express.Router();
router.get('/customers', function(req, res, next) {
console.log(req.status())
res.send('<p>some html</p>');
});
router.post('/customers/update/shipping', function(req, res) {
res.send('<p>someg html</p>');
});
router.post('/customers/update/billing', function(req, res) {
res.send('<p>somew html</p>');
});
router.post('/customers/update/cart', function(req, res) {
res.send('<p>some dhtml</p>');
});
module.exports = router;
<------------------------------------------------------>
In your customers files your routes will already be relative to /customers. remove the leading /customers from all your routes. For e.g:
router.get('/customers', function(req, res, next) {
console.log(req.status())
res.send('<p>some html</p>');
});
Should just be
router.get('/', function(req, res, next) {
console.log(req.status())
res.send('<p>some html</p>');
});
same principle applies for the other files.

socket emit an event on http PUT

I am using expressjs, nedb, and socket.io. Various (non-browser) clients are able to PUT new values into the db successfully. When that happens, I want a message emitted to all browsers connected to the server. I have the following code which is currently not sending a message back to the browser.
// on the server
//***************************************************************
// reachable to the world at http://server/foo
// clients can PUT data into the db
app.put('/foo', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
io.sockets.emit('PUT a new value', { added: newDoc._id });
res.send('Success! Find it again with id: ' + newDoc._id);
});
});
// reachable to the world at http://server/
// browser shows a dashboard of events
app.get('/', function(req, res, next) {
// code to serve the dashboard here
});
io.sockets.on('connection', function (socket) {
socket.on('foo', function (data) {
io.sockets.emit('PUT a new value', data);
})
});
// in the browser
//***************************************************************
var socket = io.connect('/');
socket.on('PUT a new value', function (data) {
console.log(data);
});
Data get inserted into the db successfully from different non-browser clients, but the connected browser doesn't receive an update.
What am I doing wrong?
I found a solution which I don't like at all but it works. We can add io object to req or to res in the middleware like that:
app.use(function (req, res, next) {
req.io = io;
next();
});
before app.use('/', routes) and then in our router module we "import" the io object:
app.put('/foo', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
var io = req.io; // HERE !!!
io.sockets.emit('PUT a new value', { added: newDoc._id });
res.send('Success! Find it again with id: ' + newDoc._id);
});
});
I know, I know... let's find something else :-)
I have the following app structure generated by express generator. I start the app with $ DEBUG=foo:* npm start
.
|____app.js
|____bin
| |____www
|____data
|____LICENSE
|____node_modules
|____package.json
|____public
| |____stylesheets
| |____javascripts
| |____images
|____README.md
|____routes
| |____index.js
| |____readings.js
| |____sensors.js
| |____users.js
|____views
| |____error.hjs
| |____index.hjs
In app.js
var express = require('express');
var app = express();
var io = require('socket.io')();
app.io = io;
// notice the `(io)` for the routes that need to be socket-aware
var routes = require('./routes/index');
var users = require('./routes/users');
var sensors = require('./routes/sensors');
var readings = require('./routes/readings')(io);
…
// start listening with socket.io
app.io.on('connection', function(socket){
console.log('a user connected');
});
module.exports = app;
Then in ./routes/readings.js
var express = require('express');
var app = express();
var router = express.Router();
module.exports = function(io) {
router.put('/', jsonParser, function(req, res, next) {
if (!req.body) return res.sendStatus(400);
db.insert(req.body, function (err, newDoc) {
io.emit("reading", {id: newDoc._id});
res.send('Success PUTting data! id: ' + newDoc._id);
});
});
return router;
}
Finally, in the index.hjs template for the client-side
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('reading', function (data) {
console.log(data);
});
</script>
The above works. When data are inserted into the db via an http PUT (see readings.js), an event is emitted by io.emit('reading', data) and the browser receives that event and shows it in the console with socket.on('reading', function (data) { … });

Defaulting route to /api/:version in MEANJS

I am relatively new to MEANJS, i have also been reading through its documentation to learn more.
so, i am trying to create a rest API using meanjs using its yo generator and removing the angular parts of it, so far it has been a success.
What i am trying to do now is to default the url routes to have a prefix of /api/:version, what i did so far is to append the /api/:version to the routes inside app/ like the following
//app/routes/articles.server.routes.js
'use strict';
...
module.exports = function(app) {
// Article Routes
app.route('/api/:version/articles')
...
app.route('/api/:version/articles/:articleId')
...
// Finish by binding the article middleware
app.param('articleId', articles.articleByID);
};
That works so far, but can i declared this somewhere so that i don't have to add /api/:version every time i create a new route?
I tried implementing the ones stated in express documentation and Remi M's answer in this stackoverflow question with no luck.
Update
meanjs installation comes with an express.js, so i thought that this is the right place to do it and i tried using the router object to solve this problem, although it doesn't work
//config/express.js
'use strict';
...
var express = require('express');
...
var router = express.Router();
module.exports = function(db) {
var app = express();
...
app.use(function(req, res, next) {
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
app.use(compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
...
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(app);
});
app.use(function(err, req, res, next) {
if (!err) return next();
console.error(err.stack);
res.status(500).render('500', {
error: err.stack
});
});
app.use(function(req, res) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not Found'
});
});
...
app.use('/api/:version', router); //this is what i add
return app;
};
All of your initial configurations should be on router object and not on app For Ex :
'use strict';
var express = require('express');
var router = express.Router();
module.exports = function(db) {
var app = express();
router.use(function(req, res, next) {
res.locals.url = req.protocol + '://' + req.headers.host + req.url;
next();
});
router.use(compress({
filter: function(req, res) {
return (/json|text|javascript|css/).test(res.getHeader('Content-Type'));
},
level: 9
}));
config.getGlobbedFiles('./app/routes/**/*.js').forEach(function(routePath) {
require(path.resolve(routePath))(router);
});
router.use(function(err, req, res, next) {
if (!err) return next();
console.error(err.stack);
res.status(500).render('500', {
error: err.stack
});
});
router.use('/bar', function(req, res, next) {
console.log("bar endpoint called");
res.send("bar");
});
router.use(function(req, res) {
res.status(404).render('404', {
url: req.originalUrl,
error: 'Not Found'
});
});
app.use('/api/:version/', router); //this is what i add
return app;
};
Then call app.use("prefixurl",router) as above.
test the BAR API /api/v1/bar