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

In Javascript, a variable is being defined by combining a string with another variable through concatenation

Hey, I'm relatively new to working with Javascript and am facing an issue that I believe can be resolved easily with the right syntax. The problem lies in setting a variable (totalRow1) where it needs to be concatenated with a string and another vari ...

Is there a way to extract just the date portion from the string "2017-11-13T00:00:00" using AngularJS?

I am looking for a way to extract only the date portion from "2017-11-13T00:00:00" using AngularJS. I attempted to achieve this using the following method: &scope.date = "2017-11-13T00:00:00"; var dateParts = $filter('date')(new Date(&sc ...

The "model" feature appears to be inactive

I discovered a fiddle with a simple radio button functionality that I forked and made some modifications to. The changes worked perfectly, you can check it out in this fiddle: Vue.component('radio-button', { props: ['id', 'v ...

Exploring Django with Selenium: How to Extract Page Content Using find_element

I have been attempting to extract the text 'Incorrect Credentials' using selenium. Here is what I have experimented with... message_text = self.driver.find_element(By.XPATH, '//*[@id="toast-container"]/div/div[1][@class="ng-binding toast-t ...

Dynamic refresh of content with Ajax

Recently, I stumbled upon the platform Polyvore and decided to test it out. While experimenting with its "Create a set" feature, I noticed that the site provides a view of items either from your own collection or sourced elsewhere. An interesting observat ...

Initializing the $scope of an AngularJS directive or controller

I decided to place the init() function outside of the return statement in my directive : app.directive('myDirective', function() { return { restrict: 'C', controller: function($scope) { init($sco ...

Is it possible to replicate an HTML table using JavaScript without including the headers?

Discover a JavaScript snippet in this stack overflow post that allows you to create a button for automatically selecting and copying a table to the clipboard. When pasting the data into an Excel template, my users prefer not to include the header informat ...

TaffyDB is throwing an error message indicating that TAFFY is not recognized as a function

I am currently developing a web-based game using HTML, CSS & JavaScript within Visual Studio and utilizing TaffyDB as my database. However, I have encountered an error when trying to create a database using the TAFFY function, as it keeps showing up in the ...

How to manage script loading while loading a page via Ajax requests

How can scripts loaded through Ajax page calls be managed to prevent conflicts with those already loaded on the base page? Would it be best to create separate pages for normal calls (with the scripts) and Ajax calls (without duplicate scripts)? For examp ...

Knockout Mapping is causing a complete re-render of all elements

Utilizing the Knockout mapping plug-in to update the UI with JSON data fetched from the server every 3 seconds. The UI contains nested foreach bindings. However, it appears that all elements within the foreach bindings are completely erased and re-rendered ...

Utilizing d3.json: changing the URL with dynamic data

Just getting started with d3 and building a sankey diagram. I came across a sample that uses an external .json file with d3.v3, even though it is an outdated version. Since my tree also relies on this version, I'd like to stick to just one d3 version. ...

Is it Possible to Achieve Callbacks From AJAX to PHP Despite the Inability to Serialize Closures?

Question How can I incorporate a PHP callback passed via AJAX, where the callback is executed by the page requested through AJAX? The Scenario Comments are submitted through AJAX with parameters serialized and encrypted for security. The issue arises wh ...

Struggling to display Firestore data in a React component - useRef() does not trigger re-render and useState() throws an error

I am currently working on a project involving a React component called Dashboard. The component includes various features such as loading data from a Firestore database and displaying it on the page. While implementing this functionality, I encountered an ...

The autocomplete feature is not displaying the data in the Bootstrap modal, only the list is visible

Having trouble with autocomplete in the bootstrap modal. The search for a book only shows black dots. Any solutions to this issue? As shown in the image, I've attempted to use CSS z-index but the problem persists. https://i.sstatic.net/e1ga9.png publi ...

Encountering an Axios Error 404 while attempting to save my information to the MongoDB database

I am encountering an Axios error 404 when trying to register details in a MongoDB database. The error message I am getting is - "Failed to load resource: the server responded with a status of 404 (Not Found)." You can view the Error 404 Image for reference ...

Having trouble getting event modifiers to work in Vue when added programmatically

Trying to dynamically add events using v-on through passing an object with event names as keys and handlers as values. It appears that this method does not support or recognize event modifiers such as: v-on=“{‘keydown.enter.prevent’: handler}” T ...

Dropdown search menus are failing to appear in the correct location

I have 4 dependent search dropdown menus side by side. There are two issues I am facing: Whenever I type in any of the drop-down menus, the MySQL-connected lists appear but not directly beneath the actual 'input-type-search-box'. Additional ...

Exploring the World with GPS Technology and Coding

Starting off, I am looking to develop a web-based or browser-based application in the near future. The goal is to incorporate a GPS module as part of the interface for a self-hosted application on tablets or laptops, utilizing the data for tracking purpo ...

`Issues encountered while converting PHP Array to JSON format`

I've been encountering difficulties converting a multidimensional PHP Array to JSON. While using json_encode, the result is null. I'm working on developing an orgChart where the data is extracted from a CSV file and stored in an array. The layou ...

Conceal any ng-repeat elements that do not contain corresponding grandchildren within two levels of nested ng-repeats

Apologies for the enigmatic title, but the issue at hand is quite cryptic ¯\_(ツ)_/¯ I'm dealing with a complex problem involving 3 nested ng-repeats to display Google Analytics' account structure. Within this structure are multiple acco ...