12

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);.

2 Answers 2

6

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);
            }
        });
    });
Sign up to request clarification or add additional context in comments.

Comments

3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.