I'm writing an application where I use express, Node.js and MongoDB (using mongojs). I have a module db.js
and a server.js
, which have the snippets below.
db.js
var getUsersByCity = function(city, callback) {
db.users.find({'city': city}).toArray(function(err, data) {
if (err) {
callback(err);
console.log(err);
} else {
console.log(data);
callback.json(data);
}
});
}
server.js
app.post("/get_users_list", function(req, res) {
var body = req.body;
db.getUsersByCity(body.city, res);
});
It's working because, as you can see, I'm (probably incorrectly) using callback.json(data)
, when I should be using callback(data)
. I think the db.js
module should not be responsible for sending the response and I should pass res.json
as the callback to my function.
The problem is: when I do things the way I consider right, I face the following error:
path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/connection/base.js:245
throw message;
^
TypeError: Cannot call method 'get' of undefined
at res.json (path_to_my_app/node_modules/express/lib/response.js:189:22)
at path_to_my_app/db.js:36:13
at path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/cursor.js:163:16
at commandHandler (path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/cursor.js:706:16)
at path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/db.js:1843:9
at Server.Base._callHandler (path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/connection/base.js:445:41)
at path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/connection/server.js:468:18
at MongoReply.parseBody (path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js:68:5)
at null.<anonymous> (path_to_my_app/node_modules/mongojs/node_modules/mongodb/lib/mongodb/connection/server.js:426:20)
at EventEmitter.emit (events.js:95:17)
How to properly send the JSON response without sending the response object to my DB module?
P.S. The content of line 36 of db.js
, when I make the changes, is callback(data);
.
You're right that db.js
shouldn't call res
or even know about it. It's good to keep it separated.
Following this (untested):
db.js
var getUsersByCity = function(city, cb) {
db.users.find({'city': city}).toArray(cb);
}
server.js
app.post("/get_users_list", function(req, res) {
var body = req.body;
db.getUsersByCity(body.city, function(err, data){
if (err) {
console.log(err);
return res(err);
} else {
console.log(data);
return res.json(data);
}
});
});
Two overall problems I see:
First, your db.js file should do something like:
callback(err, data);
Second, your server.js call should look more like:
db.getUsersByCity(body.city, function(err, data){
if(err){
res.send(500, "something went wrong");
}else{
res.json(data);
}
});
The db.getUsersByCity call is asynchronous because you can't read anything until the database call comes back on it's callback. I didn't read too much of the error though.. See if that clears things up at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With