2

I have a problem with the AngularJs forEach operation. I want to iterate through my resouce Services an save the id of each item. I think this must be really easy but somehow I just can't figure it out. My recent approach looks like this:

CIS.factory('Services', function($resource) {
return $resource('/CIS/webresources/service/');

});

function ServiceCtrl($scope, Services) {

$scope.ServiceResult = Services.query();

$scope.getIds = function() {
    angular.forEach($scope.ServiceResult, function(eachService) {
           console.log(eachService.id);        
    });

};

$scope.getIds();
}

But its not doing anything inside the forEach braces. I'm thankful for any advice. Also alternate ways of getting the ids would be appreciated.

1
  • What does the $resource('/CIS/webresources/service/') contain? Commented Oct 19, 2013 at 9:11

3 Answers 3

1

Sound like $scope.ServiceResult return promise and you run forEach before, actually, got data. The other problem should be that query() method returns nothing at all.

So we will try both options:

If $resource('/CIS/webresources/service/') is async:

Try to change your factory and call method like:

CIS.factory('Services', ['$resource','$q',  function($resource, $q) {
    var data = $resource('/CIS/webresources/service/'); 


       var factory = {
            query: function () {
                var deferred = $q.defer();              
               deferred.resolve(data);                
                return deferred.promise;
            }
        }
        return factory;
}]);

And call it in controller:

          Services.query() // query() returns promise 
                        .then(function (result) {
                          angular.forEach(result, function(eachService) {
                           console.log(eachService.id);        
                            });
                        }, function (result) {
                            alert("Error: No data returned");
                        });

A promise represents a future value, usually a future result of an asynchronous operation, and allows us to define what will happen once this value becomes available, or when an error occurs.

Here is Demo in Fiddle that can help you

If $resource('/CIS/webresources/service/') is not async:

CIS.factory('Services', ['$resource','$q',  function($resource, $q) {
    var data = $resource('/CIS/webresources/service/'); 

       var factory = {
            query: function () {               
                return data;                
            }
        }
        return factory;
}]);

And controller (like yours):

$scope.ServiceResult = Services.query();

$scope.getIds = function() {
   angular.forEach($scope.ServiceResult, function(eachService) {
       console.log(eachService.id);        
  });
};

relevant Example: Fiddle

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

6 Comments

Thank you for your quick reply. The second suggestions seems to work somehow although I can't get the ids through eachService.id. So this is my first new problem. The second problem is that I also display the services by using a ng-repeat and this doesn't work anymore. I guess this is because now I'm returning 'factory' an not 'data'.
Try to modify my Fiddle I posted for your needs to help me to help you :). BTW, i suggest you to debug it check what eachService returns
Can you post '/CIS/webresources/service/' content?
the content is something like: [{"id":3,"user":{"id":1,"password":"tpw","role":"user","name":"TestUser"},"name":"TestService","anbieter":"TestAnbieter"},{"id":11,"user":{"id":1,"password":"tpw","role":"user","name":"TestUser"},"name":"TestService2","anbieter":null}]
It works when I put the data directly in there like in your example. But not when I get it from my RESTful Service. That's strange. The data I postet is exactly what I receive from the get-request. I checked with RESTClient.
|
1

The problem you have is clearly that $ressource() returns always a promise.

That means, its an asynchronous call to your server, which return sometime in the future.

The synchronous return value you get from $ressource() is a promise object which will - when the http request is done - get the result in the future.

In the current stable version of angularJS (1.0.x) all promises that are referenced in your templates will get automatically resolved and browser will display it once its resolved. (This will change in angularJS 1.2)

However, your $scope.getIds function can be called before the $ressource promise is resolved and angular.each can't work with a promise object.

BTW: the second suggestion by Maxim is quite problematic as it contains a hard to debug timing problem. The service is issueing a $ressource() call when its parsed the first time by angularJS. At the time as factory.query() is called, the $ressource() call can be done ... or not, its not guaranteed that its already done!

I would change your original code to this (somewhere in your controller):

Services.query().then(function(result) {
   $scope.ServiceResult = result;
   angular.forEach(result, function(eachService) {
       console.log(eachService.id);        
   });
});

Comments

0

In AngularJS 1.5, the .query() function does not directly return a promise. You need to call

Services.query().$promise.then(function(result) {
  angular.forEach(result, function(eachService) {
    console.log(eachService.id);        
  });
});

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.