0

I'm creating a dynamic FormArray within a FormGroup. The only change I've made is switching from *ngFor to the new @for. The issue occurs when I try to remove an element from the FormArray.

Previously, I simply used the remove function, and it would remove exactly the element where I clicked. However, with the new @for, the behavior is different. Even though the correct index or element is removed from the FormArray, in the DOM, it visually removes the last element of the list instead.

For example, if I have five elements and delete the second one, the FormArray correctly removes that index. But in the UI, the last element disappears instead, making it seem like the last option is being deleted rather than the intended one.

 @for (opcion of listaOpciones.controls; track $index; let a = $index){
          <div class="row mb-2 mb-md-0 card_opciones" [formGroupName]="a" >
            <div class="titulo_mobile mb-2 etiqueta col-12"></div>
            <div class="col-1 contenedor_quitar">
              <button class="col-2 btn boton_quitar" (click)="deleteOption(a)" type="button">
                <i class="fas fa-minus"></i>
              </button>
            </div>
          </div>
        }

My function to delete is this.

deteleteOption(index: any) {
    this.listaOpciones.removeAt(index);}

3 Answers 3

1

The problem is that you're deleting, for example, index 0 from the array, but in the HTML, when it loops through, it sees that the array has one less element, and as a result, the last index is no longer there. You need to have something unique—you can use the reference from the control directly:

html @for (option of listaOpciones.controls; track option; let a = $index){

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

Comments

0

The problem is in the track $index; expression. According to the docs:

Select a property that uniquely identifies each item in the track expression. If your data model includes a uniquely identifying property, commonly id or uuid, use this value. If your data does not include a field like this, strongly consider adding one.

For static collections that never change, you can use $index to tell Angular to track each item by its index in the collection.

If no other option is available, you can specify identity. This tells Angular to track the item by its reference identity using the triple-equals operator (===). Avoid this option whenever possible as it can lead to significantly slower rendering updates, as Angular has no way to map which data item corresponds to which DOM nodes.

Comments

0

It should either be

@for (opcion of listaOpciones.controls; track $index;

or

@for (opcion of listaOpciones.controls; track a; let a = $index)

When you set let a = $index, it means that the index is available under a, instead of $index.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.