totalnoob
totalnoob

Reputation: 2741

returning value from mongoose aggregate on asynchronous

Writing a helper to get the friendship of two users to see if they've confirmed their friendship or if it's pending or something else .

result[0].friends[0].status comes back as either 0, 1 or 2.

eg.

[ { id: 59974d2915a07e09b88e3b4b, status: 1, _id: 59974d9015a07e09b88e3b53 } ]

I'm using the following helper method to try and get that value which works fine but I can't seem to set it.

UserSchema.methods.getRelationship = function getRelationship(username, userid, callback) {

var relationship = 0;

User.aggregate([
{
    $match: {
        username: username,
        'friends.id': userid
        }
    },
    {
        $project: {
            friends: {
                $filter: {
                    input: '$friends',
                        as: 'fr',
                        cond: {
                            $eq: ['$$fr.id', userid]
                        }
                    }
                }
            }
        }
    ], function (err, result) {
        if (err) {
            console.log(err);
            return;
        }
        if (result.length >= 1) {
            relationship = result[0].friends[0].status;
        }
    }
);

return relationship;
}

but

user.getRelationship(req.params.username, req.session.user.id)

returns undefined. why?

updated code

app.get('/:username', requireLogin, function(req, res, next) {
    var relationship = 0;
    user.getRelationship(req.params.username, req.session.user.id, function(err, r) {
        // r should be 1
        relationship = r;
    });

    res.render("user", {
        data: user,
        relationship: relationship,
        layout: 'user'
    })
}
})

})

relationship gets passed back to the (handlebars) view as 0

Upvotes: 2

Views: 1166

Answers (1)

Mikey
Mikey

Reputation: 6766

Because you're doing an asynchronous call -- you can't return from an asynchronous call.

What you can do is pass a callback in your method -- which you have done. Except you did not call it. Once you get a result from your inner callback, call the main callback.

UserSchema.methods.getRelationship = function (username, userid, callback) {
    var relationship = 0;
    User.aggregate([
        // ...
    ], function (err, result) {
        if (err) 
            return callback(err);
        if (result.length)
            relationship = result[0].friends[0].status;
        callback(null, relationship);
    });
});

You would then use it

user.getRelationship(req.params.username, req.session.user.id, function (err, relationship) {
     console.log(err, relationship);
     res.render(/* ... */);
});

Aside, this function looks better as a static as it does not involve the current user.

Upvotes: 3

Related Questions