13

I wanna update an object within an objects array. Is there another possibility than iterating over all items and update the one which is matching? Current code looks like the following:

angular.module('app').controller('MyController', function($scope) {
    $scope.object = {
        name: 'test',
        objects: [
            {id: 1, name: 'test1'},
            {id: 2, name: 'test2'}
        ]
    };

    $scope.update = function(id, data) {
        var objects = $scope.object.objects;

        for (var i = 0; i < objects.length; i++) {
            if (objects[i].id === id) {
                objects[i] = data;
                break;
            }
        }
    }
});
5
  • 3
    What does the view look like? If you have a reference to the object where you're calling update(), pass in the object instead of the id. Commented Nov 4, 2014 at 17:22
  • adding to anthony's suggestion.. ng-click="update(obj, data)" instead of ng-click="update(obj.id, data)" Commented Nov 4, 2014 at 17:25
  • Also, do you want to check the id before adding? I believe, that is not needed in your case? Commented Nov 4, 2014 at 17:29
  • @DominikBarann added the answer. Commented Sep 12, 2015 at 14:27
  • @Dominik consider accepting an answer! Commented Jan 4, 2018 at 5:58

4 Answers 4

7

There are several ways to do that. Your situation is not very clear.

-> You can pass index instead of id. Then, your update function will be like:

$scope.update = function(index, data) {
    $scope.object.objects[index] = data;
};

-> You can use ng-repeat on your view and bind object properties to input elements.

<div ng-repeat="item in object.objects">
    ID: <input ng-model="item.id" /> <br/>
    Name: <input ng-model="item.name" /> <br/>
</div>
Sign up to request clarification or add additional context in comments.

2 Comments

Added a plunker below
If you are trying to update by id, then index does not necessarily correspond to id. You can end up with the wrong record.
7

Filters that help in finding the element from the array, can also be used to update the element in the array directly. In the code below [0] --> is the object accessed directly.

Plunker Demo

$filter('filter')($scope.model, {firstName: selected})[0]

Comments

6

Pass the item to your update method. Take a look at sample bellow.

function MyCtrl($scope) {
  $scope.items = 
    [
      {name: 'obj1', info: {text: 'some extra info for obj1', show: true}},
      {name: 'obj2', info: {text: 'some extra info for obj2', show: false}},
    ];
  $scope.updateName = function(item, newName){
     item.name = newName;
  } 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app>
  <table ng-controller="MyCtrl" class="table table-hover table-striped">
    <tr ng-repeat="x in items">
        <td> {{ x.name }}</td>
        <td> 
           <a href="#" ng-show="!showUpdate" ng-click="someNewName = x.name; showUpdate = true">Update</a>
           <div ng-show="showUpdate" ><input type="text" ng-model="someNewName"> <input type="button" value="update" ng-click="updateName(x, someNewName); showUpdate = false;"></div>
         </td>
    </tr>

  </table>
</body>

Comments

2

Going off your plunker, I would do this:

  • Change

    <a href="javascript:;" ng-click="selectSubObject(subObject.id)">Edit</a>
    

    to be

    <a href="javascript:;" ng-click="selectSubObject($index)">Edit</a>
    
  • Then use the array index within your $scope.selectSubObject method to directly access your desired element. Something like this:

    $scope.selectSubObject = function(idx) {
      $scope.selectedSubObject = angular.copy(
        $scope.selectedMainObject.subObjects[idx]
      );
    };
    

If however, you only have the id to go off of, then you can use the angular filterService to filter on the id that you want. But this will still do a loop and iterate over the array in the background.

See documentation for ngrepeat to see the variables that it exposes.

3 Comments

Note that angular.copy will create a new object so you won't get the 2-way binding that angular is really useful for. If you he's plain to update the main object with his changes, then I don't think the angular.copy is necessary.
Yes it's better to use the index here instead of the id, but the problem is still the same. I have to update the object in my main object and dont know really how to do that, because i dont know the index. I use the copy method because the user should can go back without saving the changes. If i refer to the real object any changes will be saved without pressing the save button. My problem is the save method of my SubObjectController. Added a fork plnkr.co/edit/YcPMe0uFWFNgDpZddjt6?p=preview
If the objective is to NOT loop over the array and you do not have the index then that is not possible. As I mentioned before, you can use the angular $filter service to filter your array, but this does a loop under the covers. Example of using the $filter service: $filter('filter')($scope.selectedMainObject.subObjects, {id: $scope.selectedSubObject.id). Another option (what I would do) is to redesign the implementation to save off the index. I've updated your plunker to save of the index: plnkr.co/edit/5udyU3o1AR5z5dP1ReFJ?p=preview

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.