AsyncNodeJS: Error: Callback was already called

AAA picture AAA · May 31, 2015 · Viewed 9.3k times · Source

I am new to node.js and I have to solve a bug in it. I am trying to update the group members by the following service and whenever I try to call this API, I got error as

Error: Callback was already called.

My code is:

'app.post('/api/updateGroup/:group_id', function (req, res) {
  var checkGroup = Group.findOne({'_id': req.params.group_id}).exec();
    checkGroup.addBack(function( err , existingGroup ) {
        if ( err ) {
            res.json({'message' : err });
        }else if( existingGroup ){

Group.findOne({ '_id': req.params.group_id })
        .execQ()
        .then(function(existingUser) {
            var friendphoneNumber = req.body.friendphoneNumber.split(',');

            var friends = [];
            console.log('existingUser', friendphoneNumber);

            async.each(friendphoneNumber, function(phonenum, callback) {

                var phonenum = phonenum.split("\'")[0];
                console.log('phonenum', phonenum);

                User.findOne({
                    'phoneNumber': phonenum
                })
                .execQ()
                .then(function(existingFriend) {

                    if(existingFriend === null) {
                        friends.push({
                            'details': {
                                'phoneNumber': phonenum
                            }
                        });
                        callback();

                    } else {

                        friends.push({'details': existingFriend});
                        callback();
                    }

                })
                .catch(function(err) {
                    console.log('err', err)
                    friends.push({
                        'details': {
                            'phoneNumber': phonenum
                        }
                    });
                    callback();
                 })
                .done(function() {

                });

            }, function(err) {
                console.log('callback')

                group.group_id = req.params.group_id;
                // group.user_id = req.body.userId;
                // group.createdDate = moment().format('YYYY-MM-DD hh:mm a');

                group.friends = friends;

                group.update(function(err) {
                    if (err) {
                        res.json({
                            message: err
                        });
                    } else {

                        res.json({
                            success: 1,
                            message: 'Group updated',
                            group: group
                        });
                    }
                });


            });

        })
        .catch(function(err) {
            res.json({
                success: 0,
                message: 'user id Not Match. Please try again'
            });

        })
        .done(function(events) {


        });
    }
    else {

        console.log('nope');
    }

});


});

I have seen few answers regarding the same, but still I can't solve it.

Answer

Aaron Dufour picture Aaron Dufour · May 31, 2015

If callback throws an error, it is going to get called in both the then and the following catch. You should probably be calling it in the done function.

            .then(function(existingFriend) {

                if(existingFriend === null) {
                    friends.push({
                        'details': {
                            'phoneNumber': phonenum
                        }
                    });
                } else {

                    friends.push({'details': existingFriend});
                }

            })
            .catch(function(err) {
                console.log('err', err)
                friends.push({
                    'details': {
                        'phoneNumber': phonenum
                    }
                });
             })
            .done(function() {
                callback();
            });