2

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.

1
  • 1
    use promise inside your service Commented May 31, 2016 at 11:15

4 Answers 4

1

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

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

2 Comments

Thanks for the reply. What's the best approach in your opinion? Someone has answered me to use a factory instead of a service, what do you think? About the side note: actually I've deleted $interval.cancel in the example because I don't know where to put it. Just below $interval ? I don't think it is safe. Or do you mean inside if (customizeData)?
Ok it works by putting $interval.cancel inside $interval
0

if you want to get the return data, you would write a factory instead of service!

code:

myApp.factory('ajaxcall', ['$http', function($http) {
  return {
    getjson : function () {

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

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

1 Comment

I'll try it, but I've learned the service pattern on w3schools. Please give it a look on the "Create Your Own Service" section. w3schools.com/angular/angular_services.asp Why shouldn't it work in my case?
0

You are misusing the promise returned by your asynchronous call. Here is what you need to do in your controller to change the data:

ajaxcall.getjson()
.then(function(new_items) {
    // customize data

    // this part should go here as well
    for(var i=0; i<new_items.length; i++) {
      $scope.items.push(new_items[i]);
    }
});

No need to use intervals or timeouts. Pay attention, ajaxcall.getjson() does NOT return your data, it returns the promise resolved with your items.

Read about the promises in angular.

Comments

0

use promise when your making http calls from service

myApp.service('ajaxcall', ['$http', '$q', function($http, $q) {
    this.getjson = function() {
      var q = $q.defer();
      $http.get("http://localhost:3000/one")
        .success(function(data) {
          console.log(data); //data logged correctly
          q.resolve(data);
        })
      .error(function(err) {
        q.reject(err);
      });
      return q.promise;
    }
  }]);

changes in controller to wait for promise

ajaxcall.getjson()
 .then(function(data){
    console.log(data);
 });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.