1

I have an empty ngModel=titel, on click, I'm adding empty input field in my template. Trouble is, that I cant remove exactly that field what I wont. My splice always deleting last field there is my ts

app.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})
export class AppComponent {
  inputFields = [];

  addSome() {
    this.inputFields = ['', ...this.inputFields];
  }

  deleteSome(val: number) {
    console.log(val);

    const index = val;
    if (index !== -1) {
      this.inputFields.splice(index, 1);
    }

    console.log(index);
  }
}

and my html

app.html

<mat-icon (click)="addSome()">add</mat-icon>

<div class="form-group" *ngFor="let item of inputFields; index as i">
  <input type="text" class="form-control" name="price" [(ngModel)]="item[i]" />
  <mat-icon (click)="deleteSome(i)">delete</mat-icon>
</div>

and stackbiz: stackbiz

Juden1938
  • 91
  • 11

3 Answers3

2

The most important point is that you should not use i on your item.

item is already representing each item in your list, so access it directly.

Also, you need to make your array an array of objects, so that Angular can track them. (Ideally, you would not use a simple counter for assigning id properties, this is just for demonstration purposes. You could also use that id, to delete from the array if desired, using filter etc.)

https://stackblitz.com/edit/angular-ivy-twsm7e

app.html:

<button (click)="addSome()">add</button>

<div class="form-group" *ngFor="let item of inputFields; index as i">
  <h6>{{item.id}}</h6>
  <input type="text" class="form-control" name="price" [(ngModel)]="item.text" />
  <button (click)="deleteSome(i)">delete</button>
</div>

app.ts

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
   inputFields = [];
   currentId = 0;

  addSome() {
    this.inputFields = [...this.inputFields, {text: "", id: this.currentId}];
    this.currentId ++;
    console.log(this.inputFields)
  }

  deleteSome(val: number) {
    console.log(val);    
    this.inputFields.splice(val, 1);
    console.log(this.inputFields)
  }
}

Alternative:

using id and filter instead of index and splice, to delete items:

app.html

<button (click)="addSome()">add</button>

<div class="form-group" *ngFor="let item of inputFields">
  <h6>{{item.id}}</h6>
  <input type="text" class="form-control" name="price" [(ngModel)]="item.text" />
  <button (click)="deleteSome(item.id)">delete</button>
</div>

app.ts

import { Component, VERSION } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
   inputFields = [];
   currentId = 0;

  addSome() {
    this.inputFields = [...this.inputFields, {text: "", id: this.currentId}];
    this.currentId ++;
    console.log(this.inputFields)
  }

  deleteSome(id: number) {
    console.log(id);    
    this.inputFields = this.inputFields.filter(item => item.id != id)
    console.log(this.inputFields)
  }
}
Alex L
  • 4,168
  • 1
  • 9
  • 24
1

I updated your stackblitz example and this should work fine. Here you can find more detailed example. Input tame should be unique and also u had bad [ngModel] mapping.

There is an explanation

You're iterating the items you're editing and they are primitive values. ngFor can't keep track by identity because when the value changes from 1 to 3 (by editing) it becomes a different identity. Either use a custom trackBy that tracks by index or use objects instead of primitive values.

tprieboj
  • 1,680
  • 6
  • 31
  • 54
0

Splice is working fine in your code. If you check the console, you can see that there are errors when entering values in the input controls.

The problem is in the way you are using the ngModel for the inputs.

A similar scenario was mentioned in this StackOverflow question, the accepted answer there is the solution to the issue.

Alternatively, You can use the Reactive Forms to achieve your use case easily.

I have updated your stackbliz. You can see the magic and power of reactive forms here.

I would suggest you to use Reactive Forms to build better forms.

Harish
  • 714
  • 5
  • 11