1

Hello: im gettin my feet wet in AngularJS. I am trying to add and remove elements in an array; however, im unable to accomplish the desired effect.

the foll is the JSON structure:

    $scope.masters = [
    {
"name": "Wittgenstein",
"thoughts": ["thought 1", "thought 2", "thought 3"]

},

{
"name": "King",
"thoughts": ["thought 1", "thought 2", "thought 3"]

}
  ];

the foll is the plunker.

Plunker

any input is greatly appreciated. thank you.

1
  • @Matthew do you mean sthg like this; although it's not workin either: $scope.add = function() { $scope.masters.thoughts[$index].push($scope.input); $scope.input = ''; }; Commented Mar 29, 2016 at 17:06

4 Answers 4

2

As @Mathew suggested, you should introduce the usage of $index as follows:

JS code:

$scope.input = [];

$scope.add = function(i) { // receiving index as param
    $scope.masters[i].thoughts.push($scope.input[i]);
    $scope.input[i] = '';
};

HTML code:

<div ng-repeat="master in masters">
  <h1>{{ master.name }}</h1>
  <ul>
    <li ng-repeat="thought in master.thoughts">
      {{ thought }} <button ng-click="remove($index)">Remove</button>
    </li>
  </ul>
  <input type="text" ng-model="input[$index]">
  <button type="submit" ng-click="add($index)">Add</button>
</div>

See this Plunker working example

Sign up to request clarification or add additional context in comments.

2 Comments

okay.. so one needs to use indices for working with nested arrays.Now i seem to be applying similar logic with removing a thought but it doesnt seem to work.. what may i be missing here. $scope.remove = function(i) { $scope.masters[i].thoughts[i].splice(index, 1); };
aah.. i was getting the argument wrong. it works now $scope.remove = function(master, i) { master.thoughts.splice(i, 1); }; and thanks Leo, im goin thru your code line by line to try and absorb the concept of working with arrays. i have upvoted your answer, but its not gettin reflected as i dont have sufficient points.
0

You need to specify the index of masters. Something like this should work in the remove function:

$scope.masters[masterIndex].thoughts.splice(index, 1);

where masterIndex is the index of the master that you want to remove a thought from

1 Comment

i've also tried this: $scope.remove = function(index) { var index = $scope.masters.indexOf(master); $scope.masters[masterIndex].thought.splice(index, 1); };
0

the problem is that you need pass to the add and remove functions the index of the masters. Because you do this:

$scope.masters.thoughts.splice(index, 1);

But masters is an Array, therefore you need to select one object inside that Array, for example

$scope.remove = function(masterIndex, thoughtsIndex) {
    $scope.masters[masterIndex].thoughts.splice(thoughtsIndex, 1);
};

For this to work in your HTML you have to use the parent index inside the inner ng-repeat

<div ng-repeat="master in masters">
    <h1>{{ master.name }}</h1>
    <ul>
        <li ng-repeat="thought in master.thoughts">
            {{ thought }}
            <button ng-click="remove($patent.index, $index)">
                Remove
            </button>
        </li>
  </ul>
  <input type="text" ng-model="input">
  <button type="submit" ng-click="add($index)">Add</button>
</div>

In the Add function you must do the same to recibe the $index of the masters array.

Comments

0

This is an updated version of your plnkr.

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script data-require="[email protected]" data-semver="1.4.0" src="https://code.angularjs.org/1.4.0/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="demoController">

    <div ng-repeat="master in masters track by $index">
      <h1>{{ master.name }}</h1>
      <ul>
        <li ng-repeat="thought in master.thoughts track by $index">
          {{ thought }} <button ng-click="remove(master, $index)">Remove</button>
        </li>
      </ul>
      <input type="text" ng-model="input[$index]">
      <button type="submit" ng-click="add($index)">Add</button>
    </div>

  </body>
</html>

Notice how I included the current master as an argument to the remove function. This ensures that the correct master is spliced since JavaScript arrays are passed by reference. Below is the updated angular controller.

var app = angular.module('app', []);

app.controller('demoController', ['$scope', function ($scope) { 

  $scope.input = [];

  $scope.masters = [ {
    "name": "Wittgenstein",
    "thoughts": ["thought 1", "thought 2", "thought 3"]
  }, {
    "name": "King",
    "thoughts": ["thought 1", "thought 2", "thought 3"]
  }];

  $scope.add = function(index) {
     $scope.masters[index].thoughts.push($scope.input[index]);
     $scope.input[index] = '';
  };

  $scope.remove = function(master, index) {
    master.thoughts.splice(index, 1);
  };
}]);

The add function seems not to be picking the value from the input model, but then that should be a binding issue, not the function not working as it should.

Working Plunkr

I hope this helps.

1 Comment

thank you so much for takin the time out to help me with his. im gonna go through your code line by line to try and absorb the concept of working with arrays. thanks v much. i have upvoted your answer, but its not gettin reflected as i dont have sufficient points.

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.