简体   繁体   中英

function is returning value before mongoose findById api responds the data

I am trying to alter messages array to add userId in each objects.

router.post('/messages', (req, res) => {
    var users = req.body.users;
    users.sort();
    Room.findOne({ users: users }, (err, room) => {
        if (!room) {
            res.status(400).send(errorResponse(null, "Message Not Found."));
        } else {
            Message.find({ roomId: room._id }, (err, messages) => {
                if (messages.length > 0) {
                    var alteredMessages = [];
                    for (var i = 0; i < messages.length; i++) {
                        var userId = messages[i].userId;
                        var body = messages[i].body;
                        var createdAt = messages[i].createdAt;
                        var updatedAt = messages[i].updatedAt;

                        console.log("1. Calling findUserById");
                        findUsersById(userId, myCallBack);
                        function findUsersById(id, callback) {
                            console.log("2. Inside findUserById");
                            User.findById(id, (err, user) => {
                                if (!user) {
                                    console.log("user not found");
                                } else {
                                    console.log("3. Got User");
                                    callback(user);
                                }
                            });
                        }
                        function myCallBack(user){
                            console.log("4. Inside myCallBack. Pushing data to array: " + user.name);
                            alteredMessages.push(
                                {
                                    userId,
                                    userName: user.name,
                                    body,
                                    createdAt,
                                    updatedAt
                                }
                            );
                        }
                    }
                    setTimeout(function () {
                        var messageResponse = {
                            messages: alteredMessages,
                            users: users
                        };
                        console.log("5. Sending response");
                        console.log(messageResponse);
                        res.send(successResponse(messageResponse, "Messages Successfully Found."));
                    }, 10);
                }
            });
        }
    });
});

This is the result of console logs in my terminal. alteredMessages array is responding messages but all data are last index data of original messages array. I am using callback but i don't know whats wrong with it.

1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
1. Calling findUserById
2. Inside findUserById
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel 2
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel 2
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel 2
3. Got User
4. Inside myCallBack. Pushing data to array: Manjul Sigdel 2
5. Sending response
{ messages:
[ { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel 2',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel 2',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel 2',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z },
    { userId: '5a49c4417335cd272819d2d1',
    userName: 'Manjul Sigdel 2',
    body: 'hi bro',
    createdAt: 2018-01-12T10:22:05.911Z,
    updatedAt: 2018-01-12T10:22:05.911Z } ],
users: [ '5a39fc56e07695104059736f', '5a49c4417335cd272819d2d1' ] }

Seeing the response it looks like findUserById function is returning from the function before User.findById() responds the user. How do i solve this?

The problem in your code is that you send the response with a setTimeout. You should send the response inside your callback function myCallBack . Just like this.

function myCallBack(user){
    console.log("4. Inside myCallBack. Pushing data to array: " + user.name); 
    alteredMessages.push( { userId, userName: user.name, body, createdAt, updatedAt } ); 
    var messageResponse = { messages: alteredMessages, users: users };
    console.log("5. Sending response"); 
    console.log(messageResponse); 
    res.send(successResponse(messageResponse, "Messages Successfully Found.")); }
}

You have declared variable in loop and in loop java script does not wait for below function's response so you have to push your data above before the function and pass index for change user name in my below snippet i solved your issue. follow

var alteredMessages = [];
for (var i = 0; i < 4; i++) {
    var userId = i;
    var body = "Hello" + i;
    var createdAt = "crea" + i;

    alteredMessages.push({
        userId,
        userName: "",
        body,
        createdAt

    });

    console.log("1. Calling findUserById");
    getUserId(i, i, myCallBack);
}

function getUserId(i, index, callback) {
    console.log("2. Inside findUserById");
    setTimeout(function() {

        if (index == 2) {

            callback("Devraj" + i, index);
        }

    }, 1000)
}

function myCallBack(username, index) {
    console.log("4. Inside myCallBack. Pushing data to array: ");

    alteredMessages[index].userName = username;

}

setTimeout(function() {
    console.log(alteredMessages);
}, 2000);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM