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

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.