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.CommentedNov 4, 2014 at 17:22
  • adding to anthony's suggestion.. ng-click="update(obj, data)" instead of ng-click="update(obj.id, data)"
    – Kevin B
    CommentedNov 4, 2014 at 17:25
  • Also, do you want to check the id before adding? I believe, that is not needed in your case?
    – Asik
    CommentedNov 4, 2014 at 17:29
  • @DominikBarann added the answer.
    – Artiom
    CommentedSep 12, 2015 at 14:27
  • @Dominik consider accepting an answer!CommentedJan 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> 
2
  • Added a plunker belowCommentedNov 5, 2014 at 13:12
  • 2
    If you are trying to update by id, then index does not necessarily correspond to id. You can end up with the wrong record.
    – Sam
    CommentedMay 8, 2017 at 15:22
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]

    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>

    0
      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
      • 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.
        – T.V.
        CommentedNov 5, 2014 at 14:36
      • 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=previewCommentedNov 5, 2014 at 19:00
      • 1
        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=previewCommentedNov 18, 2014 at 15:15

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.