Return variable from method in a loop

Problem

Something like this

var joined = function(arr) {
    var res = [];
    for (var i in arr) {
        var u = DB.getUser(arr[i].user_id, function(user) {
            return user;
        });
        arr[i].user = u;
        res = arr[i];
    }

    return res;
}

I need to get user variable from DB.getUser scope.

Problem courtesy of: user2194521

Solution

Is just inserted some comments into you code to help understand the async flow:

var joined = function(arr) {
    // Timestamp: 0
    var res = [];
    for (var i in arr) {
        // Timestamp: 1
        var u = DB.getUser(arr[i].user_id, function(user) {
            // Timestamp 4 ... length of arr
            // user contains what you are looking for
            // but this is not return to u, because we passed that a long time ago
            return user;
        });
        // u is null or undefined, because DB.getUser returns nothing
        // is a async function, you need wait for the callback
        arr[i].user = u;
        // Timestamp: 2 return useless arr
        res = arr[i];
    }
    // Timestamp: 3 again, return a useless array
    return res;
}

Edit:

You need to this before you pass everything to the template, e.g.:

var joined = function(arr, doneCallback) {
    var res = []
    var count = arr.length;
    for (var i in arr) {
        DB.getUser(arr[i].user_id, function(user) {
            count--;
            res.push(user);
            if (count == 0) {
                doneCallback(res);
            }
        })
    }
}

joined(somedata, function(mydata) {
    render(template, mydata)
});

Take a look at some flow control libraries. (My favorite async)

Solution courtesy of: TheHippo

Discussion

var getJoinedAndDoSomeThingWithThem = function(ids) {
var joined = [];
var i = 0;

var getAUser = function () {
    DB.getUser(ids[i].user_id, function(user) {
        joined.push(user);
        i++;
        if (i == ids.length -1) {
            doSomeThingWithTheResult(joined);
            return;
        }
        getAUser();
    });
}
getAUser();
}
Discussion courtesy of: eosterberg

This recipe can be found in it's original form on Stack Over Flow.