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