I am new using nodejs and express
and was wondering what is the best practice to manipulate data before render a view. Currently i want to set some variables based on the retrieved data to render the view. So far this is what i have, but I am not sure if this is the best practice or if there is any better way to do it.
var request = require('request');
module.exports = function(req, res, next) {
request.get('http://nout.nout-app.com/getAccessVIPForUserId/' + req.params.id, function(err, resp, body) {
var bodyResp = JSON.parse(body);
bodyResp.data.forEach(function(el, index, array){
if(el.access_status === '1') {
el.status = 'success';
} else {
el.status = 'warning';
}
if(el.access_friend === '1') {
el.access_friend = 'yes';
} else {
el.access_friend = 'no';
}
});
console.log(bodyResp.data);
if(err || (typeof bodyResp.data === 'undefined' || bodyResp.data === null)) {
res.render('error', {
message: bodyResp.reason ? bodyResp.reason : 'Something went wrong',
error: {
status: 500
}
});
} else {
res.render('profile', {
intern: true,
user: req.user,
invitations: bodyResp.data
});
}
});
};
I appreciate if you guys could give me guide in this and also suggest some good material to improve. Regards.
Yes, .forEach is blocking (synchronous), but it is extremely fast. In general you don't need to worry about for basic data manipulation like that. Remember - async doesn't make something take less time, it just gives other things the ability to keep happening in the mean time.
If you really want to make your loop async, have a look at the async module. async.each is an async version of .forEach
Related
I've spent quite a bit of time looking to see if there is anything available that will run blocks of route level middleware conditionally.
Ideally the solution would require no changes to the middlewares, and they could just be passed in as an array.
I have just implemented a very crude solution but wanted to see what people think, what issues I'm likely to face and whether there is just a better solution to this.
An example of the problem I am trying to solve is middleware1 altered something on the request that meant middleware2, 3 & 4 do not need to run.
Here's my crude solution:
function conditional({ condition, field, value }, middleware) {
const conditions = {
eq: (_this, _that) => {
return _this === _that;
},
};
return (req, res, originalNext) => {
if (!conditions[condition](_.get(req, field), value)) {
return originalNext();
}
let i = 0;
function next() {
if (i === middleware.length) {
return originalNext();
}
if (typeof middleware[i] === 'function') {
i += 1;
middleware[i - 1](req, res, next);
}
}
next();
};
}
app.get(
'/test-conditional/:condition',
middleware1,
conditional({ condition: 'eq', field: 'params.condition', value: 'run' }, [
middleware2,
middleware3,
middleware4,
]),
middleware5,
async (req, res, next) => {
res.sendFile(path.join(__dirname + '/index.html'));
}
);
Any feedback or pointers in the right direction would be much appreciated.
I am new to node js programming and trying to develop an API using node js, I am able to retrieve the expected output from the built API but I would like to perform some exception handling. For that I would like to check whether the request params coming from URL are not null. Below is my code:
async function getDetails(input) {
// using knex to execute query
return queries.getbymultiwhere('table_name',{
name:input.name,
id:input.id,
role:input.role
})
}
router.get('/:name/:id/:role',(req,res)=>{
getDetails({
name:req.params.name,
id:req.params.id,
role:req.params.role}).then(Results=>{ Do something with results}
})
In above code I want to check that name, id and role param values are not null.
Any helpful solution will be appreciated.
Thank you!
You can create a middleware which checks those parameters.
function check(fields) {
return (req, res, next) => {
const fails = [];
for(const field of fields) {
if(!req.query[field]) {
fails.push(field);
}
}
if(fails.length > 0){
res.status(400).send(`${fails.join(',')} required`);
}else{
next();
}
};
}
app.get('/api', check(['name', 'id', 'role']), (req, res) => {
getDetails()...
});
I'd like to remove an object element from my user object, I'm using pull to remove it, but it returns
TypeError: user.company.pull is not a function
router.put('/reset', passport.authenticate('jwt', {session:false}), (req, res, next)=> {
user = req.user;
var id_student = user.id;
var id_company = user.company;
var results = [];
User.findById(id_student, function(err, user) {
if(err) {
console.log(err);
return res.status(500).send({message: "Error"});
}
if(!user) {
return res.status(404).send({message: "User Not Found"});
}
user.company.pull({'company': id_company});
res.send(user);
});
});
Effectively, user.company.pull is probably undefined, rather than the function that you're looking for.
If user.company doesn't exist, then user.company is going to be undefined, and there's not a pull method defined on undefined. This means that you're effectively trying to call undefined.pull({'company': whatever}), which will never work.
Try adding a guard to ensure that you have a company attached to a user, in the same way you check to ensure that the user exists. For example:
if (!user.company) {
return res.status(404).send({ message: 'Company not found'});
}
Use 'use strict'; at top of js files.
Read https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode for more information
Check if variable user has property copmany or not and handle it.
Use this condition
if(!user || !user.hasOwnProperty('company')) {
return res.status(404).send({message: "User Not Found"});
}
I'm very new to node.js, specifically express.js. I'm working on express.js app to export some rest apis and I found that I have many dup codes that I would like to avoid this issue. I'm seeking a best practice solution. This is my made-up examples:
// app/routes/category.js
exports.create = function (req, res) {
categoryModel.create(someData, function (error, category) {
if (Util.isError(error)) {
res.send(400, error);
} else {
res.send(category);
}
});
};
// app/routes/product.js
exports.create = function (req, res) {
productModel.create(someData, function (error, product) {
if (Util.isError(error)) {
res.send(400, error);
} else {
res.send(product);
}
});
};
You can see that both my create routes codes are pretty much the same but just different model (product vs category) my questions are:
1) is there a way to do inheritance in node.js/express.js?
2) is there a way to do interface in node.js/express.js?
3) what is the best way to avoid duplicate code as above samples?
4) I was thinking of it is possible to have parent class and let both category and product classes inherits from parent. I really do not how it should be done in node.js
I read couple of node.js books but I don't see authors mentioned much about how to architect app in correct or at least best practice.
I read about Prototype.js, is it the right path to go?
Any thoughts and helps would be very appreciated!
There's no need for inheritance (especially since handlers have to be functions so it's hard for me to see how you can use inheritance here). You can simply create a function generator:
var generate_handler = function(model) {
return function(req, res) {
model.create(someData, function (error, obj) {
if (Util.isError(error)) {
res.send(400, error);
} else {
res.send(obj);
}
});
};
};
and then you do
// app/routes/category.js
exports.create = generate_handler(categoryModel);
// app/routes/product.js
exports.create = generate_handler(productModel);
I'm trying to have a total message count for a user's inbox displayed within my layout. I was thinking that I needed to use Express' dynamicHelpers to do this, but in Express <= 2.x, these are not async calls, and I need to do some async processing within them: in this case, a database call with a callback.
I'm trying the following to place the count within my session, which itself is put in a dynamicHelper accessible to the views. However, due to the asynchronous nature of these callbacks, session.unreadMessages is always undefined.
messageCount: function(req, res) {
var Messages = require('../controllers/messages'),
messages = new Messages(app.set('client'));
if(req.session.type === 'company') {
messages.getCompanyUnreadCount(req.session.uid, function(err, result) {
req.session.unreadMessages = result[0].unread;
});
} else if(req.session.type === 'coder') {
messages.getCoderUnreadCount(req.session.uid, function(err, result) {
req.session.unreadMessages = result[0].unread;
});
}
return;
}
Is there another or better way to perform this task?
It should be noted that req.session.unreadMessages is defined (at least within that callback), but undefined when session is called using the helper.
Not sure, it it would be a 'best way', but I'm used to using a filter (or a so called middleware) to load data before it reaches the actual destiny, like in:
filters.setReqView = function(req,res,next) {
req.viewVars = {
crumb: [],
flash_notice: augument,
}
somethingAsync(function(err,data){
req.viewVars.someData = data
next()
})
}
app.all('*', filters.setReqView )
// then on my request:
...
res.render('auth/win', req.viewVars )
Refactoring your code you would have:
app.all('*', function(req, res, next) {
if(req.session && req.session.type){
var Messages = require('./controllers/messages'),
messages = new Messages(app.set('client'));
if(req.session.type === 'company') {
messages.getCompanyUnreadCount(req.session.uid, function(err, result) {
req.session.messageCount = result[0].unread;
next();
});
} else if(req.session.type === 'coder') {
messages.getCoderUnreadCount(req.session.uid, function(err, result) {
req.session.messageCount = result[0].unread;
next();
});
}
} else {
next()
}
});