1

I’m having an issue with my project. In my angularjs controller a function is being executed and then my function to make a call to my database to update a record is executing without waiting for the first function to complete and therefore sending over an undefined result variable.

Below you can find my code snippets with my attempts so far.

Submit button function:

$scope.submitNewStarters = function () {

    // result is returning as undefined <<<<< Issue
    var result = $scope.sendNewStarterDetailsToApi();

    $scope.updateArchivedImportFlag(result); 

};

Controller function handling the logic:

$scope.sendNewStarterDetailsToApi = function () {

swal({
    title: "Confirmation",
    text: "Are you sure you want to import the new starter details?",
    icon: "info",
    dangerMode: true,
    buttons: ["No", "Yes"]
}).then(function (approve) {

    if (approve) {

        // Get each of the new starter details that have been set to true for import.
        var newStartsToImport = $scope.tableParams.data.filter(x => x.imported == true);

        for (let i = 0; i < newStartsToImport.length; i++) {

            // Parses the current new starter object into a stringified object to be sent to the api.
            $scope.newStartsToImport = $scope.createApiObject(newStartsToImport[i]);

            // A check to ensure that nothing has went wrong and that the stringify object has worked.
            if ($scope.newStartsToImport !== "") {

                apiFactory.postNewStarterDetailsToApi($scope.newStartsToImport).then(function (response) {

                    var isSuccessful = response.data.d.WasSuccessful;

                    if (isSuccessful)
                        toastr.success("New starter details successfully sent to API.", "Success!");
                    else {
                        var errorMessage = response.data.d.ErrorMessage;
                        toastr.error("New starter details were unsuccessfully sent to API. Please try again. \n" + errorMessage, "Error!");
                    }

                });
            }
            else {
                toastr("An error has occurred when attempting to create the data object to be sent to API. The process has stopped!", "Error!");
                break;
            }
        }

        return newStartsToImport;
    }
    else
        toastr.info("No new starter details were sent to API", "Information!");
    });
};

Factory function for API call:

postNewStarterDetailsToApi: function (data) {
    return $http({
        url: "https://www.example.com/services/service.svc/Import",
        method: "POST",
        data: data,
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
        }
    }).then(function successCallbwack(response) {
        // this callback will be called asynchronously
        // when the response is available
        return response;
    }, function errorCallback(response) {
        // called asynchronously if an error occurs
        // or server returns response with an error status.
        console.log('An error has occured during the function call postNewStarterDetailsToApi(): ', response);
    });
}    

So with the concept of promises how am I able to execute the sendNewStarterDetailsToApi function, wait for it to complete and then return the populated array? Once the populated array (result) is returned then execute the updateArchivedImportFlag function.

Below I've added an illustration of what I'd like to achieve:

For loop logic

2
  • i suggest you to make a single request with the updated elements, making asynchronous requests on a loop wont work as the loop will continue to execute and wont wait for then Commented Oct 5, 2018 at 12:34
  • 1
    I appreciate the quick and kind comeback. Commented Oct 9, 2018 at 10:08

1 Answer 1

1

The approach I am using is , save all the promises in an array . Use any promise library or es6 Promise, and use .all function to wait for all promises to execute

The syntax i wrote is not totally correct. Since you are using angular js , you can use $q.all

$scope.sendNewStarterDetailsToApi = function () {

    swal({
        title: "Confirmation",
        text: "Are you sure you want to import the new starter details?",
        icon: "info",
        dangerMode: true,
        buttons: ["No", "Yes"]
    }).then(function (approve) {
        var res = [];
        if (approve) {
    
            // Get each of the new starter details that have been set to true for import.
            var newStartsToImport = $scope.tableParams.data.filter(x => x.imported == true);
    
            for (let i = 0; i < newStartsToImport.length; i++) {
    
                // Parses the current new starter object into a stringified object to be sent to the api.
                $scope.newStartsToImport = $scope.createApiObject(newStartsToImport[i]);
    
                // A check to ensure that nothing has went wrong and that the stringify object has worked.
                if ($scope.newStartsToImport !== "") {
                    res.push(apiFactory.postNewStarterDetailsToApi($scope.newStartsToImport))
                }
                else {
                    toastr("An error has occurred when attempting to create the data object to be sent to API. The process has stopped!", "Error!");
                    break;
                }
            }
    
            return Promise.all(res);
        }
        else
            toastr.info("No new starter details were sent to API", "Information!");
        }).then(function (data) {
            data.forEach((response) => {
                var isSuccessful = response.data.d.WasSuccessful;

                if (isSuccessful)
                    toastr.success("New starter details successfully sent to API.", "Success!");
                else {
                    var errorMessage = response.data.d.ErrorMessage;
                    toastr.error("New starter details were unsuccessfully sent to API. Please try again. \n" + errorMessage, "Error!");
                }
            })
        }).then((res) => {
            //call Submit new starters
        })
    };

Sign up to request clarification or add additional context in comments.

4 Comments

Your solution appears to work for me however there's one last outstanding bit that I can't seem to resolve. The last promise .then((res) => {. res is coming through as undefined. How could I use the res variable to contain an array of the results sent to the api successfully?
Yes. res is undefined since we did not return anything from previous then. Just return what you want in previous then and you can access it
thanks for that explanation. Your proposed solution has resolved my issue. Thanks for the help.
It's hard to see that this answer solves the problem given that $scope.sendNewStarterDetailsToApi() still returns undefined. It should return Promise and $scope.submitNewStarters() should be rewritten accordingly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.