Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't change result from MongoDB/MongooseJS in route before sending it to the view (Node js)

In my route I am trying to replace a value in whatever i get from the database before sending it to my view.

In this case I am trying to replace a reference to a user, with the users username instead. But my console.log's just keep returning the value unchanged.

app.get('/message/inbox', function(req, res) {
    var _id = req.user._id;
    var inbox = null;
    var users = null;
    async.parallel([
        function(callback){
            Inbox.find({to: _id}, callback);
        },
        function(callback){
            User.find({}, callback);
        }
    ],
    function(err, result){
        inbox = result[0];
        users = result[1];
        for(var i = 0; i < inbox.length; i++) {
            for(var j = 0; j < users.length; j++) {
                if(String(inbox[i].from) == String(users[j]._id)) {
                    inbox[i].from = users[j].local.username;
                    console.log(users[j].local.username);
                    console.log(inbox[i].from);
                    break;
                }
            } 
        }
        console.log(inbox);
    });
});

This is what my console returns:

[email protected]
540468daeb56d5081ade600d
[ { _id: 54084cacf212815422aabe94,
    from: 540468daeb56d5081ade600d,
    to: 5406bf4c8a8acc88120922dc,
    headline: 'Some Headline',
text: 'Some text',
__v: 0 } ]
like image 270
Jesper Nielsen Avatar asked Jan 10 '23 21:01

Jesper Nielsen


2 Answers

What gets returned from the find requests is a "mongoose document" which is actually quite complex and contains all the rules and methods from the associated schema. You cannot modify this outside of the constraints set on the schema.

So despite the simple serialized form, the object is quite complex. What you want is just a basic object, so you can modify it however you want. So put simply, just call .toObject() to get the "raw" JavaScript object without the rest of the sugar:

inbox = result[0].toObject();
users = result[0].toObject();

The basic objects have no methods and no rules. Modify away.

like image 141
Neil Lunn Avatar answered Jan 15 '23 19:01

Neil Lunn


Solution by OP.

I just have to add a .lean() after the .find. This tells mongoose to pass the data as a javascript object instead of a MongooseDocument - Scource

app.get('/message/inbox', function(req, res) {
    var _id = req.user._id;
    var inbox = null;
    var users = null;
    async.parallel([
        function(callback){
            Inbox.find({to: _id}, callback).lean();
        },
        function(callback){
            User.find({}, callback).lean();
        }
    ],
    function(err, result){
        inbox = result[0];
        users = result[1];
        for(var i = 0; i < inbox.length; i++) {
            for(var j = 0; j < users.length; j++) {
                if(String(inbox[i].from) == String(users[j]._id)) {
                    inbox[i].from = users[j].local.username;
                    console.log(users[j].local.username);
                    console.log(inbox[i].from);
                    break;
                }
            } 
        }
        console.log(inbox);
    });
});
like image 42
Cœur Avatar answered Jan 15 '23 20:01

Cœur