AngularJS resource promise
Asked Answered
R

4

76

I've got a simple controller that use $resource :

 var Regions = $resource('mocks/regions.json');

 $scope.regions = Regions.query();

I'm using this controller in a directive (in the link function)

var regions = scope.regions;

But regions is undefined. It's pretty logic the call is asynchronous.

My question is how can i do to wait the result and regions be an array with all data ?

UPDATE : 

Here the definition of the directive

app.directive('ngMap', function() {
  return {
    restrict: 'EA',
    replace: 'true',
    scope: {

    },
    template: '<div id="map"></div>',
    controller: 'AccordMapCtrl',
    link: function(scope, element, attrs) {
      var regions = scope.regions;
      console.log(regions);

      for (var region in regions) {}
    };
  });
Rhu answered 21/10, 2013 at 9:20 Comment(3)
I had the same problem and used the solution by @AndreyPushkarev inside the link function. Basically all the logic in the link function is inside $promise.then(function(result){...});.Cox
Just to make sure I'm not misunderstanding - the "callback" approach to solving this problem technically works just as well as the "promises" approach, correct? (I prefer the syntax of promises, but it seems to me that callbacks would technically accomplish the same thing)Bernettabernette
Yes you get the choice $promise.then or a simple callback. The $promise approach is more "semantic" i guessRhu
H
186

If you want to use asynchronous method you need to use callback function by $promise, here is example:

var Regions = $resource('mocks/regions.json');

$scope.regions = Regions.query();
$scope.regions.$promise.then(function (result) {
    $scope.regions = result;
});
Howenstein answered 16/11, 2013 at 13:3 Comment(7)
Why make the two intermediate assignments? If, as I expect, Regions is not used elsewhere, then resource('mocks/regions.json').query().$promise.then(function (result) { $scope.regions = result; }); would surely do the job.Daiseydaisi
can be helpful to have intermediate assignments when debugging codeCowpea
From $resource docs: ...invoking a $resource object method immediately returns an empty reference...This is a useful trick since usually the resource is assigned to a model which is then rendered by the view. Having an empty object results in no rendering, once the data arrives from the server then the object is populated with the data and the view automatically re-renders itself showing the new data.Making
OK, but does my version without intermediate assignments not behave in the same way? Nothing will be rendered until $scope.regions = result executes.Daiseydaisi
@Daiseydaisi I agree with you that your code is functionally equivalent to the accepted answer in this simple exercise. I'm working on a more complex app, though, that returns data to the view from multiple tables. To keep my code cleaner and to implement the DRY principle, I have abstracted invoking the $resource object away into a reusable factory. I pass the unique portion of the path as a parameter from my controller to the factory, and return the data to my controller. Doing so requires me to have intermediate assignments similar to the accepted answer.Effrontery
@steve, from what you say I would guess that intermediate assignment(s) are reasonable in your case. If you want a more considered opinion, you could always post in Code Review.Daiseydaisi
@SilvioTroia result.status; // Will contain an object with HTTP status code and name. For example: {code: 200, name: "OK"}Howenstein
F
36

If you're looking to get promise in resource call, you should use

Regions.query().$q.then(function(){ .... })

Update : the promise syntax is changed in current versions which reads

Regions.query().$promise.then(function(){ ..... })

Those who have downvoted don't know what it was and who first added this promise to resource object. I used this feature in late 2012 - yes 2012.

Finable answered 21/10, 2013 at 9:49 Comment(3)
It's available from 1.1.15. You might want to consider upgrading the version.Finable
I'm using 1.2 RC for real app. And it's a mission critical app, I just didn't try some fancy stuff they added lately. That resource promise thing was used in our app last year in angular. We just added the patch some guy suggested and Angular Team marked "Good to Merge". It's not a big deal. If you care about that much then make a custom $http wrapper and use it like resource calls and you get promises.Finable
I'm usign promise on resource in 1.0.8 it's just that the syntax is different :)Rhu
B
20

You could also do:

Regions.query({}, function(response) {
    $scope.regions = response;
    // Do stuff that depends on $scope.regions here
});
Bismuth answered 20/6, 2014 at 11:17 Comment(1)
However this is the callback syntax right, not promises?Hua
P
0
/*link*/
$q.when(scope.regions).then(function(result) {
    console.log(result);
});
var Regions = $resource('mocks/regions.json');
$scope.regions = Regions.query().$promise.then(function(response) {
    return response;
});
Pasia answered 10/6, 2017 at 3:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.