Callback was already called async parallel
Asked Answered
T

2

15

Hi I am trying to use the Async module to retrieve two users and do some processing after they have both been retrieved however I keep getting the error message: Callback was already called. Below is the code i currently have:

app.get('/api/addfriend/:id/:email', function(req, res) {
    var id = req.params.id;
    var friendEmail = req.params.email;
    async.parallel([
            //get account
            function(callback) {
                accountsDB.find({
                    '_id': ObjectId(id)
                }, function(err, account) {
                    console.log(id);
                    if (err || account.length === 0) {
                        callback(err);
                    }
                    console.log(account[0]);
                    callback(null, account[0]);
                });
            },
            //get friend
            function(callback) {
                accountsDB.find({
                    'email': friendEmail
                }, function(err, friend) {
                    console.log(friendEmail);
                    if (err || friend.length === 0 || friend[0].resId === undefined) {
                        callback(err);
                    }
                    console.log(friend[0]);
                    callback(null, friend[0].resId);
                });
            }
        ],

        //Compute all results
        function(err, results) {
            if (err) {
                console.log(err);
                return res.send(400);
            }

            if (results === null || results[0] === null || results[1] === null) {
                return res.send(400);
            }

            //results contains [sheets, Friends, Expenses]
            var account = results[0];
            var friend = results[1];
            if (account.friends_list !== undefined) {
                account.friends_list = account.friends_list + ',' + friend;
            }
            else {
                account.friends_list = friend;
            }
            // sheetData.friends = results[1];
            accountsDB.save(
                account,
                function(err, saved) {
                    if (err || !saved) {
                        console.log("Record not saved");
                    }
                    else {
                        console.log("Record saved");
                        return res.send(200, "friend added");
                    }
                }
            );

        }
    );
});

Any help would be appreciated.

Terpineol answered 17/12, 2014 at 8:47 Comment(0)
G
23

Add else statement to your code, because if you get error, your callback executes twice

if (err || account.length === 0) {
  callback(err);
} else {
  callback(null, account[0]);
}
Galitea answered 17/12, 2014 at 8:50 Comment(0)
C
12

The docs from async actually say:

Make sure to always return when calling a callback early, otherwise you will cause multiple callbacks and unpredictable behavior in many cases.

So you can do:

return callback(err);
Crossquestion answered 24/6, 2016 at 1:42 Comment(2)
did not helped.Janeth
I think both cases work. A return is more explicit and you can avoid the else syntax as well. If this did not work for you, there is a good chance you're receiving an unexpected behavior from a 3rd party, and using the if/else syntax will also create possible problems. For example, this issue: github.com/caolan/async/issues/1162Philosophy

© 2022 - 2024 — McMap. All rights reserved.