lostpacket
lostpacket

Reputation: 1401

AngularJS $http ajax request is not asynchronous and causes page to hang

I have a service where I am pulling data from server. When I click the button to send out the request to server through this service, the window freezes until I receive a response from server. Is there anything I can do to make this request asynchronous ?

Here is my service.

app.factory('service', function($http) {
  return {
    getLogData : function(startTime,endTime){
      return $http({
        url:     baseURL + 'getLogData',
        method:  'GET',
        async:   true,
        cache:   false,
        headers: {'Accept': 'application/json', 'Pragma': 'no-cache'},
        params:  {'startTime': startTime , 'endTime': endTime}
      });
    }
  };
)};

HTML.

<button ng-click="getData()">Refresh</button>
<img src="pending.gif" ng-show="dataPending" />

Code

$scope.getData = function(){
  service.getLogData().success(function(data){
    //process data
  }).error(function(e){
    //show error message
  });
}

Upvotes: 8

Views: 49850

Answers (4)

Behnam
Behnam

Reputation: 6459

use this code to config

$httpProvider.useApplyAsync(true);

Upvotes: 2

Sanjeev Rao
Sanjeev Rao

Reputation: 2297

var url = //Your URL;

  var config = {
    async:true
  };

  var promise= $http.get(url, config);
     promise.then(
     function (result) 
     {
       return result.data;
     },
     function (error) 
     {
       return error;
     }
    );

Upvotes: 0

Nathaniel Johnson
Nathaniel Johnson

Reputation: 4839

While there is some argument about the pros and cons of your approach, I am thinking that the problem is answered here: AJAX call freezes browser for a bit while it gets response and executes success

To test if this in fact part of the problem, dummy up a response and serve it statically. I use Fiddler or WireShark to get the response and then save to a file like testService.json. XHR and all of it's various derivatives like $HTTP $.ajax see it as a service though the headers might be slightly different.

Upvotes: 13

Doug T.
Doug T.

Reputation: 65619

Use the success promise, and wrap up the log data in a set of objects that you can attach to a $scope.

So instead of having your service have a blocking method, have it maintain a list of "LogEntries".

   // constructor function
   var LogEntry = function() {
      /*...*/
   }

   var logEntries = [];

   // Non-blocking fetch log data
   var getLogData = function() {
        return $http({
            url : baseURL + 'getLogData',
            method : 'GET',
            async : true,
            cache : false,
            headers : { 'Accept' : 'application/json' , 'Pragma':'no-cache'},
            params : {'startTime' : startTime , 'endTime' : endTime}
        }).success(function(data) {;
           // for each log entry in data, populate logEntries
           // push(new LogEntry( stuff from data ))...
        };
   } 

Then in your controller, inject your service and reference this service's log data array so Angular will watch it and change the view correctly

   $scope.logEntries = mySvc.logEntries;

Then in the HTML, simply do something over logEntries:

  <p ng-repeat="logEntry in logEntries">
    {{logEntry}}
  </p>

Upvotes: 3

Related Questions