Dennis Hackethal
Dennis Hackethal

Reputation: 14275

Manipulate collection returned from $resource

I have a service called Message that returns messages from an API. It simply looks like this:

app.factory('Message', function($resource) {
  return $resource('http://localhost:3000/messages/:id');
});

It works fine, and I use it in my controller to assign messages to my scope:

app.controller('MessagesCtrl', function($scope, Message) {
  $scope.messages = Message.query();
}

When I log $scope.messages in the browser's console, it looks like the following:

[$promise: Promise, $resolved: false]
  0: Resource
  1: Resource
  2: Resource
  3: Resource
  $promise: Promise
  $resolved: true
  length: 4
  __proto__: Array[0]

So far, so good - four messages. I want to be able to specifically manipulate elements from this collection, such as remove, update, and add elements.

Based on this answer, this is what I have tried to remove messages with a specific id:

$scope.messages = $scope.messages.filter(function(obj) {
  return (object.id != 6);
});

But this turns $scope.messages into an empty collection. How would I remove a specific element from this collection of resources by id? Also, how would I replace an existing element in this collection with another object?

Upvotes: 1

Views: 743

Answers (1)

PSL
PSL

Reputation: 123739

$resource does auto expansion of promise (as a convenient method) and attaches the response to the returned object itself which is very convenient when binding the data to the view (as the digest cycle that runs after promise resolution will update DOM with bound object with resolved data ), but not so much when directly manipulating the data especially when you try to access it before it is resolved. So if you want to manipulate the data you would need to wait for the promise to be resolved.

i.e:-

   //chain through the promise.
   Message.query().$promise.then(function(messages){
      $scope.messages = messages.filter(function(obj) {
       return (obj.id != 6);
      });
   });

Or you could as well do (with your existing code):

  $scope.messages.$promise.then(function(messages){
     //Since you are overwriting the object here, there will no longer be a $Promise property so be careful about it when you try to chain through elsewhere after this
     $scope.messages = messages.filter(function(obj) {
       return (obj.id != 6);
      });
  });

Upvotes: 2

Related Questions