I get user query information when use req.user at first time but in second inside function I got cannot read property user of null.
router.post("/orders", function (req, res) {
console.log(req.user);//here I can see user info!
orders.count({
customerInfo: req.user//here I can get user info!
}, function (req, count) {
if (count > 0) {
console.log(count);
orders.findOne({
customerInfo: req.user//here:cannot read property user of null
}, function (err, orders) {
products.findOne({
_id: req.body.id
}, function (err, products) {
if (err) {
console.log(err);
} else {
orders.productInfo.push(products);
orders.save(function (err, data) {
if (err) {
console.log(err);
} else {
console.log(data);
}
});
}
});
});
}
You have req in the inner function and it's overriding the outter req with the user. You can create a var outside with the user:
Example:
post("/orders", function (req, res) {
const user = req.user;
orders.count({ customerInfo: user//here I can get user info!
}, function (req, count) {
//Here you can use user
});
});
In my opinion your code is what we call callback hell, so it's advisable to refactor It using control flow, you can use promises, generator functions and other artifacts for this cases.
Related
I have a fairly extensive Node.js back-end with Express and pg-promise. Most of it is working perfectly as I expected it to.
Currently I am trying to create a function that deletes from multiple tables if I pass in a value for it to do so. My problem is that when I try to use req.body.cont (cont is a variable to continue) I get undefine
I have tried changing the names of the variables, trying to mimic how I sent data to the server before.
function removeUser(req, res, next) {
console.log(req.body.cont);
if (req.body.cont) {
console.log('hello');
deleteLocCustId(req, res, next, req.params.id);
}
db.result('delete from customer where id = $1', req.params.id)
.then(function(result) {
if (!req.body.cont) {
res.status(200).json({
status: 'success',
message: `Removed ${result.rowCount} customer`
});
}
})
.catch(function(err) {
console.log(err);
return next(err);
});
}
When I use this same method to create a customer it works perfectly.
function createCustomer(req, res, next) {
const newCustomer = new PQ(
'insert into customer(customer_name, ID, parent, symID) values ($1, $2, $3, $4)'
);
newCustomer.values = [
req.body.customerName,
req.body.cId,
req.body.parentName,
req.body.symPID
];
db.none(newCustomer)
.then(() => {
if (req.body.locationObject) {
return createLocation(req, res, next);
}
return null;
})
.catch(function(err) {
return next(err);
});
}
When I try to console.log(req.body.cont); I get undefined from my server.
I have a company that have a job opening, and other users that want to work there have to make orders to that job position. Overy order has an id of the user that make´s it. I want to also show the name of that user when the company wants to see all the orders for a job.
So, what I was doing was just get all the orders with Order.getOrder, and then get name and email from user for every order and add it to what I am going to return.
The error I´m getting is TypeError: Cannot read property 'then' of undefined in the last then
router.get("/orders", verifyToken, (req, res) => {
Order.getOrders(req.userId, (err, rows) => {
for (x in rows) {
console.log(rows[x].id);
User.forge({id: rows[x].id}).fetch({columns:['email','name']}).then(user => {
rows[x].nameTester = user.get('name');
rows[x].emailTester = user.get('email');
});
}
}).then(function(err, rows) {
res.json({orders: rows});
});
});
And this
Order.getOrders = (userData, callback)=>{
if (connection) {
const query = ...sql query...
connection.query(query, [userData], (err, result, fields) => {
if (err) {
throw err;
} else {
callback(null, result);
}
});
}
};
I'm using SailsJS as an API with Waterline connected to a MongoDB. I'm trying to put together an endpoint to edit existing DB entries but can't seem to get it to work and I'm hitting a wall as to why.
My route:
'post /edit/safety/:id': {
controller: 'SafetyController',
action: 'editSafety'
},
My controller function:
editSafety: function editSafety(req, res) {
var id = req.params.id;
Safety.findOneById(id).then((err, safety) => {
if (err) {
res.send(500, err);
return;
}
if (!safety) {
res.send(404, err);
return;
}
safety.title = req.body.title;
safety.description = req.body.description;
safety.status = req.body.status;
safety.save((err, updatedSafety) => {
if (err) {
re.send(500, err);
return;
}
res.send(200, updatedSafety);
});
});
},
Any push in the right direction would be greatly appreciated.
I don't recognize the Safety.findOneById method - is this something you have custom built? If not, then it is likely your problem.
Try swapping it for either:
Safety.findOne(id)
or
Safety.findOne({id: id})
Note that the returned object will be a model instance if the record exists, and undefined otherwise. If you decide to go with Safety.find instead then the returned value will be an array containing all models matching the query.
Looks like the main issue was transposing the response and err objects. It was successfully completing the query, but loading it into the err object which gets caught and a 500 error is thrown. So I changed that and simplified in a few other places.
editSafety: function editSafety(req, res) {
var id = req.params.id;
Safety.findOne(id).then((response, err) => {
var safety = response;
if (err) {
res.send(500, err);
return;
}
if (!response) {
res.send(404, err);
return;
}
safety.title = req.body.title;
safety.description = req.body.description;
safety.status = req.body.status;
Safety.update({
id: id
}, safety)
.then((result) => {
res.json(200, 'Ok!');
})
.catch((err) => {
sails.log.error('SafetyController.editSafety', err);
})
});
},
Hi i am trying to use two selects in one JS file in node js and sql server. I am unable to figure out the syntax for this. I need a select to get all the persons from a table and another select to count the total number of persons in that table.Will it be possible to put those two selects in a single JS file. If so can someone help me with the syntax?
Here is the code i tried and i am getting the error
"cant Set headers after they are sent"
var sql = require("mssql");
var dbConfig = {
server: "XXXXX",
database: "XXXXX",
user: "XXXXX",
password: "XXXX",
port: 1433
};
exports.list = function(req, res){
sql.connect(dbConfig, function (err) {
if (err) console.log(err);
var request = new sql.Request();
request.query('select * from PERSON', function (err, recordset) {
if (err)
console.log(err)
else
console.log(recordset)
res.render('personinfo_itwx', { data: recordset });
});
request.query('select count(*) from PERSON', function (err, recordset) {
if (err)
console.log(err)
else
console.log(recordset1)
res.render('personinfo_itwx', { data: recordset1 });
});
});
};
#Aditya I'm not sure it's the best way to do so, although I would simply make two different requests, in order to achieve what you need. As I mentioned my in my comment, easiest way, would be to use (for instance) async library. And here's example you've asked for.
WARNING: I did not look at mysql docs
const async = require('async')
// {
async.series([
function(next)
{
new sql.Request()
.query('SELECT * from PERSON', next(err, resultList))
},
function(next)
{
new sql.Request()
.query('SELECT COUNT(*) from PERSON', next(err, count))
}
], (err, result) =>
{
/*
err: String
- if any of the shown above return an error - whole chain will be canceled.
result: Array
- if both requests will be succesfull - you'll end up with an array of results
---
Now you can render both results to your template at once
*/
})
// }
Surely, if you want manipulate with errors or results once you get them - you always may push error and results to new function, play with your data, and return the callback afterwards. Like so:
function(next)
{
new sql.Request()
.query('SELECT * from PERSON', (err, resultList) =>
{
if (err)
{
return next(err, null)
}
/*
data manipulation
*/
return next(null, resultList)
})
},
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()
}
});