Removing an item from an ng-repeat loop while also dealing with a FormController within

I am encountering a significant issue with form inputs nested within the ng-repeat directive. I require an input that is an array and can vary in size; allowing users to add or remove parts of the form.

Within the ng-repeat directive, there is an ng-form element - my goal is to access the $dirty value of each element in the array. While everything seems to be working fine, there is one hiccup - removing elements does not properly update the FormControllers. Although the ng-repeat effectively removes an element from the view when it's deleted from the model, the ng-form fails to update its position accordingly.

Check out the plunker here

Before removal:

$index = 0, formRepeated.$dirty == true, model.value == 1

$index = 1, formRepeated.$dirty == false, model.value == 2

If I remove element 0 from $scope.model, the following scenario occurs:

$index = 0, FormController $dirty == true, value == 2

The attached FormController fails to update its position, retaining the values of $dirty, $touched, $error, etc.

I have exhausted all my options and seem to be at a standstill. Any suggestions on how to tackle this problem would be greatly appreciated.

Below is the HTML structure:

<div ng-controller="MyController">
  <form name="form">

    <div ng-repeat="modelPart in model track by $index">
      <div ng-form="formRepeated">
        <input type="text" ng-model="modelPart.value" name="form_{{$index}}_value">
        <button ng-click="$parent.removeFormRepeated($index)">
          Remove
        </button>
        <div>Is dirty: {{ formRepeated.$dirty }}</div>
      </div>
    </div>
    <button ng-click="addNew()">add new</button>

  </form>
</div>

Here is the JavaScript code:

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

app.controller('MyController', function MyController($scope) {

  $scope.model = [{value: 1}, {value: 2}];

  $scope.addNew = function() {
    $scope.model.push({});
  }

  $scope.removeFormRepeated = function(index) {
    $scope.model.splice(index, 1);
  };
});

Answer №1

It is important to be cautious when using $index in an ng-repeat loop, as the value of $index can cause unexpected issues. For more insight on this topic, check out this helpful resource (includes a plunker example) to understand why problems may arise due to improper handling of $index. When an item is deleted, it can lead to misbehavior in the $index value.

Answer №2

After encountering the same issue, I discovered a simple solution. The problem lies with $index as pointed out by @SaiUnique.

If your repeated element has a unique property, it's best to use that for tracking, like track by element.uniqueProperty. If not, just omit track by and rely on Angular's $$hashKey instead to maintain nested forms. Below is an example (using ControllerAs syntax and Angular v1.5.8).

html:

<div ng-controller="Controller as ctrl">
    <div ng-repeat="repeatedElement in ctrl.array">
        <div ng-form="formRepeated">
            <input type="text" ng-model="repeatedElement.value" name="description">
            <button ng-click="ctrl.removeFormRepeated(repeatedElement)">Remove</button>
        </div>
    </div>
</div>

inside controller:

var me = this;
me.removeFormRepeated = function(elementToDelete){
    //traverse the array and remove the element
    for(var i = 0; i < me.array.length; i++){
        //use Angular's $$hashKey as identifier
        if(me.array[i].$$hashKey === elementToDelete.$$hashKey){
            me.array.splice(i, 1);
        }
    }
}

For some unknown reason, using track by $index removes the correct element from the ng-repeat, but doesn't handle the corresponding FormController properly. Opting for $$hashkey or a unique property instead of $index resolves this issue.

I realize there's already an answer to this question, but I wanted to provide more insight since I struggled with this for hours myself!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Husky 5: The Ultimate Gitignore Manager

Last week, a new version of Husky was released, known as Husky 5. I came across an interesting article discussing the features and updates in this release that can be found here. Upon migrating to Husky 5 (), I discovered a new directory named .husky with ...

The replacer argument of the JSON.stringify method doesn't seem to work properly when dealing with nested objects

My dilemma is sending a simplified version of an object to the server. { "fullName": "Don Corleone", "actor": { "actorId": 2, "name": "Marlon", "surname": "Brando", "description": "Marlon Brando is widely considered the greatest movie actor of a ...

My AJAX function is not functioning as intended

I'm currently developing a time management system for my workplace. As I was coding, I implemented a feature that allows users to configure the database details similar to the setup process in WordPress. Once the data is saved successfully, I aim to d ...

Access Denied: Origin Issue with OAuth2

I am requesting an authorization code from the OAuth2 Server in order to authenticate a user with my Microsoft App. For more information, I consulted this document. This is my attempt to make the call: function httpGet(){ var theUrl = "https://lo ...

Develop an outline using D3.js for the clipath shape

After successfully creating a shape with a color gradient, I encountered the need for further customization. If you are interested in this topic, check out these related questions: Add multi color gradient for different points in d3.js d3.js scatter plot c ...

Retrieve information about the clicked item using the Backbone framework

I have a unique webpage that showcases an impressive collection of books. Each book listed on the page comes with essential information such as the title, price, and description. This data is imported from a JSON file. Excitingly, when users click on any ...

Creating clickable data columns in jQuery DataTablesWould you like to turn a column in your

How can I turn a column into a clickable hyperlink in a jQuery DataTable? Below is an example of my table structure: <thead> <tr> <th>Region</th> <th>City</th> <th> ...

The animations in AngularJS seem to be malfunctioning

I'm having trouble with animating a list in my project. I am using angularjs 1.2.0 rc1 and rc2 (separately for testing purposes). This is the code for my list: <ul class="list-group"> <li class="list-group-item" ng-repeat="object in log ...

Visit the map only after the promises have been fulfilled

In my current project, I am utilizing the loadash map function for data structuring. The data retrieved consists of a series of IDs that require querying the database and integrating the results into the map before returning. However, the data is delayed i ...

Dynamic scrolling feature for lists that moves horizontally

When working with a lengthy list, I encountered an issue with horizontal scrolling. It worked fine when the list was statically implemented as shown below. <div style="margin-top:100px;white-space: nowrap;"> <ul > <li style= ...

What is the purpose of assigning controller variables to "this" in AngularJS?

Currently, I am analyzing an example in CodeSchool's "Staying Sharp with Angular" course in section 1.5. Here is the code snippet: angular.module('NoteWrangler') .controller('NotesIndexController', function($http) { var contro ...

Displaying error messages on a form that uses ng-repeat in Angular

I am trying to dynamically generate input fields using ng repeat in Angular, but I am encountering an issue where error messages only appear on the last element. How can I make these error messages apply to each individual element? <form name="setPla ...

What is the best way to add controllers to AngularJS?

What is the best way to troubleshoot this setup? app.js var app = angular.module('app', ['ui.router', 'app.controllers']); /* Why is FooCtrl not being recognized here? */ controllers.js var controllers = angular.module(&a ...

Guide on setting an attribute value with JavaScriptExecutor in Selenium WebDriver

I am attempting to set an attribute value for all instances of the same type of <img> tag on My website, for example: <img src="images/temp/advertisement.png"> and I want to set style="display: none" so that I can hide them. I have tried the ...

Activate validation when the scope of a custom validator is modified

Consider a scenario where we have a custom validator with an input as the attribute's value. app.directive('inputRequired', function() { return { require: 'ngModel', scope: { inputRequired: '=& ...

I'm looking to display 9 images on a single page that rotate every 5 seconds between 3 different images. While I can figure out how to display one image easily, I'm

<script type="text/javascript"> var currPic = 1; var totPics = 9; var keepTime; function setupPicChange() { keepTime = setTimeout("changePic()", 5000); } function changePic() { currPic++; if (currPic > totPics) currPic = 1; var f ...

Changing the Color of an Object3D Mesh in Three.js

Seeking advice on how to update the color of a Three.js Object3D. Initially created using MeshStandardMaterial, this object is later retrieved from the scene by its ID. Is it possible to change the color of the Mesh at this stage? If needing to replace th ...

The function Jquery .stop does not exist

I am encountering an issue with the magicline.stop function while attempting to implement an underline sliding effect for my navbar. I have tried to troubleshoot the problem but have been unsuccessful so far. Below is the code snippet: <nav class=" ...

Getting rid of a cookie from the header in Reactjs

Currently, I'm developing an application with Reactjs and utilizing the Next.js framework. To manage user authentication, I've implemented cookies. However, I am facing a challenge when it comes to logging out users and removing the cookie. Could ...

Exploring the use of the Next.js page router for implementing internationalization (i18

I need assistance implementing Dutch and English language translations for my entire website. Can anyone provide guidance? I have tried using i18n localizely, but it only works for individual pages. I am looking to implement translations on a larger scale ...