Wait till response comes from $http request in AngularJS

Sheonarayan
Posted by in AngularJS category on for Advance level | Points: 250 | Views : 11894 red flag
Rating: 4 out of 5  
 1 vote(s)

In this article, we are going to learn how to wait till the $http response comes from server using AngularJS and then perform other action.
Recommendation
Read WebGrid in ASP.NET MVC before this article.

Introduction

As we all know that the current version of AngularJS (1.4.3) doesn't have ability to send synchronous request ($http service) to the server, it only sends asynchronous request and we do not have ability to set any property that forces AngularJS to send synchronous request.

Background

In real time, assume a scenario where you are trying to delete a record from the database by sending $http.delete request and then calling $http.get request to load fresh data and display to the user. If you happen to call them one after another, the chances are that you would get the data from server first and then the data gets deleted so you almost never gets fresh data from server.

The solution of this problem is to wait for the first request to finish and then the second request should be sent to the server ie. synchronous request the server. 

Using the code

Let's create a solution for the above problem. To demonstrate how to achieve this here is a sample working demo. 

In below code snippet, we have first created a service named "myService" using .factory method that is dependent on $http service. This service has two method 'serverCall' and 'anotherFunctionCall. 

The 1st function calls the server, gets the data and return to the calling function (In above scenario, this can be $http.delete request function). The 2nd function simply shows an alert (In this scenario, it can be $http.get request function). For simplicity, I have taken below example of showing alert.

<script>
    var app = angular.module("app", []);

    app.factory('myService', function ($http) {
        return {
            // 1st function
            serverCall: function () {
                return $http.get('/ServerRequest/GetData').then(function (response) {
                    alert(response.data);
                    return response.data;
                });
            },
            // 2nd function
            anotherFunctionCall: function () {
                alert("Hi");
            }
        };
    });

    app.controller("WaitController", function ($scope, myService) {

        $scope.GetAllData = function () {
            //var myData = myService.serverCall();
            //myData.then(function (result) {
            //    $scope.Details = result;
            //    myService.anotherFunctionCall();
            //});

            // this does't wa
            myService.serverCall();
            myService.anotherFunctionCall();
        };
    });
</script>

Then we have a controller that has a GetAllData function that calls both functions of the service. Below is the code snippet that simply lists the data received from the $http.get request.

<div ng-app="app" ng-controller="WaitController">
    <button ng-click="GetAllData()">Get Data</button>
    <div ng-bind="ResponseDetails"></div>
    <ul>
        <li ng-repeat="d in Details">
            {{ d.FirstName + ' ' + d.LastName + ', ' + d.Age}}
        </li>
    </ul>
</div>

If you happen to run above code as it is, you would be getting the "Hi" alert first and then another alert coming from serverCall() service function. It is because when we click the button, serverCall() function from the service is called and without waiting for its response the next line executes and anotherFunctionCall() function is called.

Solution

The solution of this problem is to use the promise returned by $http services in AngularJS and use .then function. This ensures that the first function response is received and then only code inside .then function would execute.

So the modified controller code would look like below.

app.controller("WaitController", function ($scope, myService) {

        $scope.GetAllData = function () {
            var myData = myService.serverCall();
            myData.then(function (result) {
                $scope.Details = result;
                myService.anotherFunctionCall();
            });

            //// this does't wa
            //myService.serverCall();
            //myService.anotherFunctionCall();
        };
    });
Notice that in the above code snippet, we have called the 1st function 'serverCall()' and then we are using .then function on that object and the 2nd function is being called inside .then function.

In real time scenario, we were talking about would behave like below
  1. The 'serverCall()' function would be called that will delete record from the database and then we will get the response.
  2. The 'anotherFunctionCall()' function would be called that will load the fresh data from the database.

Conclusion

The promise object returned by the $http service call are very helpful in ensuring that next call is made only when the first request is successful.

Thanks for reading, to enroll for training on AngularJS, ASP.NET MVC click here.
Recommendation
Read Using Angular $http.put with ASP.NET MVC project after this article.
Page copy protected against web site content infringement by Copyscape

About the Author

Sheonarayan
Full Name: Sheo Narayan
Member Level: HonoraryPlatinum
Member Status: Administrator
Member Since: 7/8/2008 6:32:14 PM
Country: India
Regards, Sheo Narayan http://www.dotnetfunda.com
http://www.snarayan.com
Ex-Microsoft MVP, Author, Writer, Mentor & architecting applications since year 2001. Connect me on http://www.facebook.com/sheo.narayan | https://twitter.com/sheonarayan | http://www.linkedin.com/in/sheonarayan

Login to vote for this post.

Comments or Responses

Login to post response

Comment using Facebook(Author doesn't get notification)