1

I want to make a function which fetches some info from an ajax URL. E.g in my service, I would have the following method:

this.getFavColor = function(id)
{
    return $http.get('/colors/get/' + id);
}

And in my controller, I would do the following:

$scope.favColor = UserService.getFavColor( id );

The problem however is, $scope.favColor will be assigned a promise in this case, and the only way to actually change it to the value returned by ajax, is to set a .success() callback on the promise and use it to update the value.

However, this is quickly becoming cumbersome if I have a lot of things that have to be fetched via ajax. Is there any shortcut, such as may be doing this?

this.getFavColor = function(id, variableToChange)
{
    return $http.get('/colors/get/' + id).success(function(jsonResult)
       {
         variableToChange = jsonResult.favColor;
       });
}

And then doing the following in the controller:

UserService.getFavColor( id, $scope.favColor );

Will this method actually work?

Note: I've already considered $resource but I cannot set up a REST api for my ajax, so please don't suggest it.

7
  • This should work. Have you tried it? My only doubt is since the return statement is returning not the promise directly, but calling the success method. if success also returns promise it is fine. Else you do not need to return anything or take the promise into a variable first and then call success on it, and return the promise. Commented Aug 16, 2013 at 6:48
  • @Chandermani I haven't tried it, but I'd prefer to use whichever method $resource uses to do this. Have you had a look at angular.resource.js's code and can you figure out how it does this? Commented Aug 16, 2013 at 6:50
  • You dont need a REST API to get data using $resource. As long the data is json GET would work without problem. It just needs a url to fetch data. Commented Aug 16, 2013 at 7:02
  • Have a look at http://stackoverflow.com/questions/11966252/how-does-the-resource-get-function-work-synchronously-in-angularjs, I'm using the methods described here to do this. I'll post an answer once its working Commented Aug 16, 2013 at 7:04
  • is it worth moving your favColor into the service rather than the controller? i know its not what you are asking, but it avoids the problem. Otherwise your controller really needs to know it is async and handle the promise itself Commented Aug 16, 2013 at 7:23

1 Answer 1

2

The way $resource does this is by returning an empty object immediatly and then adding data to this object once the response arrives from the server. That's why $resource can only return objects or arrays, not primitives.

ng-bind (and the shorthand {{ }}) actually resolves promises though, so this might be a better solution. I've created a plnkr with three different examples: http://plnkr.co/edit/WOrU5eMOmsgK4wuiSCHu?p=preview

// data.json: {"color":"Blue"}

app.service('UserService',function($http, $q){
  return {

    // return value can be accessed by {{value.data.color}}
    getFavColor: function(id){
      return $http.get('data.json');
    },

    // return value can be accessed by {{value}}
    getFavColorWithQ: function(id){
      var def = $q.defer();
      $http.get('data.json').success(function(data){
        def.resolve(data.color);
      });
      return def.promise;
    }

    // return value can be accessed by {{value.color}}
    ,resourceExample: function(id){
      var response = {};
      $http.get('data.json').success(function(data){
        response.color = data.color;
      });
      return response;
    }
  }
});
Sign up to request clarification or add additional context in comments.

3 Comments

For me, the 3rd option doesn't seem to update the view, it seems that it doesn't trigger angularjs's watches. $scope.$apply might be needed but for me, I get the digest already in progress message. The 2nd method works perfectly however.
The first method will only return the promise and you'd have to use the success callback, right?
Did you see my plnkr example? It shows how all methods work, you don't have to use a callback method in any of them. But both the first and second example returns promises, it's just that the first example returns a promise to a response object, and the second returns a promise to a value

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.