Search code examples
angularjsrestrestangular

Restangular how to update item in collection


I am currently fiddeling around with restangular and ui-router.

I do resolve a collection of items in my router which makes it available to the underlying controllers. I have a list of todos and i want to edit a todo. So i load a view where i can edit the item.

I get the model by $scope.todo = todos.get(id) I make a change to it and then i do $scope.todo.save() which updates the model on the server. But now i have the old item still in the collection of todos.

I want my collection to reflect the changes in the single item. I could delete the item from the collection and reinsert it afterwards, but this seems a little bit too complicated. Is there no easy way to update a model within a collection?

Update: Adding some Code

Note: The todos property gets resolved if the state is called.

If i edit a single todo i resolve it by

resolve : {
  todo : function($stateParams, todos) {
    return todos.get($stateParams.id);
  }
}

I do some changes and then i call todo.save(). No changes will happen on the collection this way. I tried to do a todos.patch(todo) but that actually did a request to weird url and i guess it is intended to patch the whole collection (?)

I am sure there is a way to change a model within a collection, but i dont know how


Solution

  • After trying some stuff i ended up with replacing the item inside the collection. I created a little helper to lodash which i want to show here:

      var replaceItemById = function(list, element) {
        var index = _.indexOf(list, _.find(list, { id : element.id }));
    
        list.splice(index, 1 , element);
    
        return list;
      };
    
      _.mixin({'replaceItemById' : replaceItemById});
    

    When i want to update a model inside a collection i do step by step:

    Fetch the collection Get a single item from the collection and edit it Call save on the item

    //The server returns the updated model
    todo.save().then(function(editedTodo) {
      _.replaceItemById(todos, editedTodo);
      $state.go('todos.index');
    });
    

    This way i do not need to fetch the collection again (even if in most cases this is what you would do) and it is up to date after updating a single item.