You need to add a trackBy so that angular can know the element which was removed, something like
HTML
<div *ngFor="let item of inputs; let i = index" class="form-row mb-2" trackBy: customTB>
<input id="inputField{{i}}" type="text" class="form-control col-sm-9" name="inputField{{i}}" >
<button (click)="remove(i)" type="button" class="btn btn-danger col-sm-offset-2 col-sm-2 ml-4">Remove</button>
</div>
TS file add the below function
customTB(index, song) { return `${index}-${song.id}`; }
It is also important to note that angular will only update the UI in the *ngFor directive if the input change
Consider below.
You add the four elements to inputs and your inputs look like below
[true, true, true, true]
Lets Remove the 3rd Element
[true, true, true]
What if I was to remove the 1st Element instead of the 3rd
[true, true, true]
Since the input is the same after both removing the 1st and 3rd ELements, angular optimization will remove the last elemen,
Now Lets amend the code
TS
inputs: string[] = [];
public addNew(): void {
this.inputs.push('');
}
public remove( index: number): void {
this.inputs.splice(index, 1);
console.log(index);
}
HTML
<div class="form-row pb-2">
<input id="field_id" type="text" class="form-control col-sm-9" name="field_id"
ngModel>
<button type="button" (click)="addNew()" [disabled]="inputs.length > 3" >+ Add</button>
</div>
<div *ngFor="let item of inputs; index as i" class="form-row mb-2">
<input [(ngModel)]='inputs[i]' id="inputField{{i}}" type="text" name="inputField{{i}}" >
<button (click)="remove(i)" type="button">Remove</button>
</div>
The above will work as long as the input is NOT the same. To ensure this always works, we add the trackBy.
Sample on Stackblitz
.indexOf()before? Try debuggingremove()function and see what all arguments it actually receives.index as isyntax, as suggested in this thread