Thomas E
Thomas E

Reputation: 521

wait for async http requests before proceeding angular

I have task groups, these groups have tasks. You can add existing tasks to your group, but also make new ones. These new ones don't have an _id yet in my mongoDB, so I have to make them first, before making my createTaskGroup call.

When I call createTaskGroup, I loop through the tasks, when there is no _id, I call "addnewtask". The problem is, that the last function "apiFactory.createTaskGroup" is called before the loop for making non existing tasks is done.

How can I wait for these functions to finish before executing createTaskGroup?

 dvm.createTaskGroup = function (){
        for (var i = 0; i < dvm.taskgroup.tasks.length; i++) {
            if (angular.isUndefined(dvm.taskgroup.tasks[i]._id)) {

                apiFactory.addNewTask(dvm.taskgroup.tasks[i].description, function (response) {
                    dvm.taskgroup.tasks[i] = response;
                });
            }
        }

            apiFactory.createTaskGroup(dvm.taskgroup, function (response) {
                $mdDialog.hide(dvm.taskgroup);
            })

    };

I also tried using promises, normally I use callbacks, but I read about $q.all. So I would give it a shot. But then I can the complain about cors even it's the same call as before but with the use of promise.

dvm.createTaskGroup = function (){
        var callsToWaitForBeforeContinue = [];

        var tempArrayWithTasksWithId = [];

        angular.forEach(dvm.taskgroup.tasks, function(task){
            if(angular.isUndefined(task._id)){
                callsToWaitForBeforeContinue.push(apiFactory.addNewTaskWithPromise(task.description));
            }
            else{
                tempArrayWithTasksWithId.push(task);
            }
        });

        $q.all(callsToWaitForBeforeContinue).then(function(req){
            dvm.taskgroup.tasks = tempArrayWithTasksWithId;

            angular.forEach(req, function(singlePromise){
                dvm.taskgroup.tasks.push(singlePromise);
            });
        });
            apiFactory.createTaskGroup(dvm.taskgroup, function (response) {
                $mdDialog.hide(dvm.taskgroup);
            });

    };

Here is the http post itself.

 var addNewTaskWithPromise = function(taskDescription){
            var q = $q.defer();

            $http.post(ENV.api + 'tasks/', taskDescription).then(function(response){
              q.resolve(response); 
            }, errorCallback);

            return q.promise;
        };

Upvotes: 0

Views: 121

Answers (2)

Thomas E
Thomas E

Reputation: 521

got it to work. I return my http call as a promise, instead of making a variable for it

    var addNewTaskWithPromise = function(taskDescription) {
        return $http.post(ENV.api + 'tasks', {
            "description": taskDescription
        });
    };

Call the function "createtaskgroup" in the "then" statement of my $q.all. Can't really explain the details why it works now, without the temp variable for my promise, I didn't receive a CORS error, probably someone here that could explain why.

dvm.createTaskGroup = function() {
        var callsToWaitForBeforeContinue = [];

        var tempArrayWithTasksWithId = [];

        angular.forEach(dvm.taskgroup.tasks, function(task) {
            if (angular.isUndefined(task._id)) {
                callsToWaitForBeforeContinue.push(apiFactory.addNewTaskWithPromise(task.description));
            } else if(angular.isDefined(task._id)) {
                tempArrayWithTasksWithId.push(task);
            }
        });

        $q.all(callsToWaitForBeforeContinue).then(function(req) {
            dvm.taskgroup.tasks = tempArrayWithTasksWithId;

            angular.forEach(req, function(singlePromise) {
                dvm.taskgroup.tasks.push(singlePromise.data.task);
            });

            apiFactory.createTaskGroup(dvm.taskgroup, function(response) {
                $mdDialog.hide(dvm.taskgroup);
            });
        });

    };

Upvotes: 0

Jacob Buczarski
Jacob Buczarski

Reputation: 97

You should be able to just call like so:

apiFactory.addNewTaskWithPromise(task.description).then(function(response){
    dvm.taskgroup.tasks[i] = response;
    apiFactory.createTaskGroup(dvm.taskgroup).then(function (response2) {
        $mdDialog.hide(dvm.taskgroup);
    });
});

Upvotes: 0

Related Questions