0

I am using waterline + sails for one api and i have the following function that has nested exec() calls.

AcademyService.getAll().exec(function (error, data) {

        if (error) {

            return res.json({result: false, message: error});

        }

        var academies = data;

        for (var i = 0; i < Object.keys(academies).length; i++) {

            var user_id;

            user_id = academies[i].academy_user_id;

            (function (index) {

                UserService.getOneById(user_id).exec(function (error, data) {

                    if (error) {

                        academies[index].academy_user_id = null;

                    }

                    academies[index].academy_user_id = data.user_fname+" "+data.user_lname;

                });

            })(i);

        }

        return res.json({result: true, academies: academies});

    });

Problem with above code is that, the last return statement does not have updated academies object. i.e. it does not have the updated value for its academy_user_id. I attribute this to the asynchronous behaviour of the calls and i think the when we reach the last return, the async calls for UserService are still running in the loop and updated academies object is not passed on.

Now, a hasty solution is to return the academies object from within the UserService.getOneById callback with a loop end check but that does not seem to be the right approach. So,can we somehow do the inner exec() synchronously?

1

1 Answer 1

1

Sails comes bundled with the async library, which is ideal for such a situation. Async is available globally in sails, so you don't need to require it, or even add it to your dependencies.

Use async.each instead of your for loop.

Something like this should work

AcademyService.getAll().exec(function(error, academies) {
    if (error) {
        return res.json({
            result: false,
            message: error
        });
    }

    async.each(
        academies,
        function (academy, cb) {
            var user_id = academy.user_id;

            UserService.getOneById(user_id).exec(function (err, user) {
                if (err) {
                    academy.academy_user_id = null;
                }
                else {
                    academy.academy_user_id = user.user_fname + ' ' + user.user_lname;
                }

                return cb();
            });
        },
        function (err) {
            if (err) {
                return res.json({
                    result: false,
                    message: err
                });
            }

            return res.json({
                result: true,
                academies: academies
            });
        }
    );
});
Sign up to request clarification or add additional context in comments.

1 Comment

Wow. I wanna know where you live :D Just the solution i wanted. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.