Search code examples
angularjspromiseangular-promiseangular-servicesangularjs-http

Angular async service


I'm trying to do an ajax call via $http service inside a custom service. Then I want to customize, inside my controller, the data received in the custom service.

I wrap the customizing data function within $interval inside the controller: by this way I can customize my data when it is received.

The problem is: while the data is correctly logged in the service, the service seems like it doesn't return anything, although it should have returned (return response.data.Items)

So $interval loops indefinitely, and I can't customize my data.

var myApp = angular.module('MyApp', []);


myApp.service('ajaxcall', ['$http', function($http) {

    this.getjson = function () {

        $http.get("http://localhost:3000/one")
            .then(function(response) {

            console.log(response.data.Items);  //data logged correctly
            return response.data.Items;
        });
    }
}])

.controller('MyCtrl', ['$scope', '$interval', 'ajaxcall', function($scope, $interval, ajaxcall) {

    var new_items = ajaxcall.getjson();

    customize_data = $interval(function () {  //loops indefintely, new_items=undefined, why?
                         if (new_items) {
                             // customize data
                         }
                     }, 200);

    for(var i=0; i<new_items.length; i++) {
        $scope.items.push(new_items[i]);
    }
}]);

You could say: just move the customize data function in the custom service. First at all I don't want to do it. Secondly it doesn't even make sense: the $scope is not available in a service, so in any case I should wait for the $http reply.


Solution

  • There were several things which I wanted to point out there.

    1. Do return $http promise from this.getjson method, so that you can chain that promise while getting data from it.

      this.getjson = function() {
        //returned promise here
        return $http.get("http://localhost:3000/one")
          .then(function(response) {
          console.log(response.data.Items); //data logged correctly
          return response.data.Items;
        });
      }
      

    1. var new_items = ajaxcall.getjson() line doesn't stored the data returned by getjson call, it will have undefined value as your currently getting. After finish up above change, new_items will hold promise return by ajaxcall.getjson. Thereafter use $q.when to keep eye on promise to get resolved & check for data inside its .then function.

      customize_data = $interval(function() { //loops indefintely, new_items=undefined, why?
        $q.when(new_items).then(function(res) {
          if (customizeData) {
            //Do Logic
          }
        })
      }, 200);
      

    Side Note: You could face problem with this code, as you had 200ms time for each interval . Which can make multiple ajax calls before completing the last call(which would be kind of unexpected behaviour). To resolve such issue you could use $interval.cancel(customize_data); //once desired interval work has done