Please, I wand to send a variable from login.js to dashbaord.js using node.js.
This is my dashboard.js:
var express = require('express');
var router = express.Router();
var Firebase = require('firebase');
var login = require('./login');
var user = login.userId;
var admin = require("firebase-admin");
var login = require('./login');
/* GET home page. */
router.get('/', function(req, res, next) {
console.log(user) // this return an undefine
res.render("pages/dashboard");
});
module.exports = router;
Thanks in advance.
The code in routes only runs when the URL pattern is hit. So in the code below the value in user will be printed out every time the "/" gets hit but you only initialized user once.
router.get('/', function(req, res, next) {
console.log(user) // this return an undefine
res.render("pages/dashboard");
});
The line for var user = login.userId; is only set once when your main express app is booted up. That is why it's coming back as undefined. But you shouldn't be passing user information from module to module this way, thats what sessions are for.
Sessions & UserIds
If you want to get the userId you should be storing it in the users session or in a cookie then you can pull it out of the request object. Any data that is specific to a user you can retrieve from your database using their userId in the session. With express theres no built in support for sessions but you can npm install middleware that will take care of this for you so that you can then write.
router.get('/', function(req, res, next) {
console.log(req.session.userId)
res.render("pages/dashboard");
});
Environment Variables
If you need to pass configuration settings around across multiple modules you can use
process.env.${propertyName} for example process.env.cat = "Henry". But that is for things you set once that are the same for all users.
Related
I'm developing part of a system where we have two applications sharing the same domain so nginx makes exampleurl.com go to one application and example.com/admin/* go to the second.
The /admin/* part is going to a NodeJs app using express.
Is there an elegant way of making sure that node can add in the /admin without having to do
app.get('/admin/endpoint', ...)
?
you can use http://expressjs.com/fr/api.html#router
var router = express.Router();
router.get('/', function(req, res) {
res.send('One page in admin website');
});
// router.get('/adminWebsite'); // idem for all routes(you always use this router)
app.use('/admin', router);
you would would to use routers (preferably) but you can also create another express app. using different Apps allow you to have more global middlewear control whereas using different routes mean that they share the same express instance.
var express = require('express');
var admin = express(); // <- this is now your admin application
var app = express(); // <- this is your main applicaiton regular users
//you will need to set up middlewear like body-parser and stuff for both of them now
//but it allows you to use different logging and authentication system or w.e you
//want
//once everything is done you can 'MOUNT' virtually the admin app to the regular app
app.use('/admin', admin); //<- this will nest apps together but allow the sub-app admin
//to be it's own instance.
//app.js
const admin = require('admin'); //you admin module (where you routes wiil be)
app.use('/admin', [functions... example authCheck], admin);
//index file of admin module
`var express = require('express');
var router = express.Router();
router.use(function authCheck(req, res, next) {
//check if user is logged
});
router.get('/main', require('./main').get);
module.exports = router;`
//main.js
`exports.get = function(req, res, next){
res.render('admin/admin', {
title: "Main panel"
});
};`
and now you can access site.com/admin/main
So basically I want my code being able to go mywebsite.com/username and itll take them to their profile.
My app.js has -
var user = require('./routes/user');
app.use('/*', user);
and then in my user.js I have
router.get('/:username', function(req, res) {
console.log('the user name', req.params.username);
})
If I change router.get to just router.get('/') my console.log logs out undefined and if I leave it as router.get('/:username') I get a 404.. I also tried doing app.use('/:username', user) as well but that still didn't work.
You should't need to have a wildcard like you do on app.use
Try something like this.
Also see the express router documentation http://expressjs.com/en/guide/routing.html
// Required Moduiles
var express = require('express');
var router = express.Router();
var app = express();
// Add route to get
router.get('/:username', function(req, res) {
res.status(200).send(req.params.username)
})
// Add username
app.use('/', router)
// Start express server
app.listen(3030);
Update -
Just using app.use(router) would do the same thing if all your routes are going to be contained in this new router instance / middleware you are creating in a separate file.
I've just made an Node.js app modular by splitting up data models and routes into separate files.
My routes are exported by express.Router(). In these routes I would like to import queried values from my app.js to be rendered with the templates.
How would I in the easiest way save things lets say with app.locals or req.variableName?
Since the route using express.Router() ties it together with app.js, should I be using app.params() and somehow make these values accessible?
Using globals seems like a worse idea as I'm scaling up the app. I'm not sure if best practice would be saving values to the process environment either using app.locals.valueKey = key.someValue...
Big thanks in advance to anyone
If I understand the question correctly, you want to pass a value to a later middleware:
app.js:
// Let's say it's like this in this example
var express = require('express');
var app = express();
app.use(function (req, res, next) {
var user = User.findOne({ email: 'someValue' }, function (err, user) {
// Returning a document with the keys I'm interested in
req.user = { key1: value1, key2: value2... }; // add the user to the request object
next(); // tell express to execute the next middleware
});
});
// Here I include the route
require('./routes/public.js')(app); // I would recommend passing in the app object
/routes/public.js:
module.export = function(app) {
app.get('/', function(req, res) {
// Serving Home Page (where I want to pass in the values)
router.get('/', function (req, res) {
// Passing in the values for Swig to render
var user = req.user; // this is the object you set in the earlier middleware (in app.js)
res.render('index.html', { pagename: user.key2, ... });
});
});
});
I'm having some trouble creating a RESTful API in Node/Express. In the app I'm building, a user has many messages, and messages belong to users. I need to be able to make an HTTP requests to retrieve all messages by a particular user. Here's the basic structure of the app, starting with the basic server, which delegates routing to a file called 'config/middleware.js'.
//server.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
require('./config/middleware.js')(app, express);
var port = process.env.PORT || 8080;
app.use(bodyParser.json());
app.use(express.static(__dirname + '/../client'));
app.listen(port);
This is the middleware file where we send requests to the appropriate router. A request made to 'users/5/messages' would get routed to the messages router, and a request made to 'users/5' would get routed to the users router.
// config/middleware.js
module.exports = function(app, express) {
var usersRouter = express.Router();
var messagesRouter = express.Router();
app.use('/users/:userId/messages', messagesRouter);
app.use('/users', usersRouter);
require('../routers/users')(usersRouter);
require('../routers/messages')(messagesRouter);
};
This is the messages router. If a get request is made to '/users/5/messages', I want the getAllMessages function to be run, which should return all messages by the user with userId 5.
// routers/messages.js
var messagesController = require('../controllers/messages');
module.exports = function(app) {
app.get('/:messageId', messagesController.getMessage);
app.get('/', messagesController.getAllMessages);
};
The problem is that the getAllMessages function doesn't have access to the 'userId' parameter (with value of 5), which is required in order to make an appropriate query to the database. The getAllMessages function in the controller expects the userId to be stored on req.params.userId. Is there any way to get the userId of 5 to be present on the req.params object inside the getAllMessages function?
The req.params are not passed down the route chain. To do so, you could do something like
In server.js, create a key on req. This will pass on your data between routes. Do this before mounting the routes.
app.use(function (req, res, next) {
req._data = {};
next();
});
In config/middleware.js,
module.exports = function(app, express) {
var usersRouter = express.Router();
var messagesRouter = express.Router();
// attach usedId
app.use('/users/:userId/messages', function (req, res, next) {
req._data.userId = req.params.userId;
next();
});
// mount the router
app.use('/users/:userId/messages', messagesRouter);
app.use('/users', usersRouter);
require('../routers/users')(usersRouter);
require('../routers/messages')(messagesRouter);
};
This way, you would have access to req._data.userId in routers/messages.js.
Side note: A better way to structure the routes would be to use something like, (read shameless plug), https://github.com/swarajgiri/express-bootstrap/blob/master/web/routes.js
You can use app.locals or res.locals to pass some datas.
There is a good explanation about locals.
An usage sample:
app.locals.userid = req.params.userId; //binding userid
app.locals.userid // => '5'
OR: put a global variable.
user_id_tmp = req.params.userId;
Now this is become global variable in app. So you can call user_id_tmp variable from anywhere.
I was looking for same.
Here is modules app example on github and auther site
Also we can change or update structure base on our requirements
REST API and Node newbie here. I'm trying to make a REST API in nodejs. Each user would be able to get items associated with their userid and the authentication mechanism is obviously separate from the url. I'm working with something like the following services.
/api/users/userid
/api/users/userid/cars/carid
I expect to have other APIs similar to the 2nd one in the future.
The issue is how to 'bind' the userid and carid or houseid parameters in a clean way. My hope was to be able to have an intermediate step which would capture the 'userid' parameter in the users.js file and then it would delegate the request to the other components. I hoped that this would allow me a more concise authentication checking but there may be more preferable ways. The problem right now is that userid is guaranteed to be unique but carid and houseid are only unique per user so I will need both values to retrieve the data.
My Question is how can I achieve this or is there a better way to organize this to facilitate concise reusable code in terms of authenticating that a user has access to that API. Also if this is very unREST-like, please correct me.
And I have the following code:
app.js
var express = require('express');
var app = express();
app.use('/api', require('./routes/api'));
var server = app.listen(3000, function() {
var host = server.address().address;
var port = server.address().port;
console.log('The server is up at ' + host + ':' + port);
});
./routes/api.js
var express = require('express');
var router = express.Router();
/* GET api listing. */
router.get('/', function(req, res, next) {
res.send('Base of our APIs');
});
router.use('/users', require('./users.js'));
router.use('/', function(req, res) {
res.send('Unauthorized api access. Not authorized for ' + req.baseUrl);
})
module.exports = router;
./routes/users.js
var express = require('express');
var router = express.Router();
router.use('/:user_id/cars', function(req, res, next) {
console.log('Userid is:' + req.params.user_id);
// Authenticate a user here before sending to the next page
var cars_api = require('./cars.js');
cars_api(req, res, next);
});
module.exports = router;
./routes/cars.js
var express = require('express');
var router = express.Router();
/* GET cars for user */
router.get('/', function(req, res, next) {
res.send('Retrieving all cars for user ' + req.params.user_id);
});
router.get('/:car_id', function(req, res, next) {
res.send('Retrieving car with car_id ' + req.params.car_id + ' and user id ' + req.params.user_id);
});
module.exports = router;
I've tried several other ways of calling the cars API that all req.params values are cleared in between. I'm using WebStorm to debug.
You would not necessarily need to write the full route like that, something you might want to look into is nested routes, I think that would help.
Rest with Express.js nested router
here you have a great example I started using when I built my first api.
At the suggestion of commenters, I have decided to just write routes directly to the cars api in the form of /users/:user_id/cars/:car_id.