Raeleen Watson
Raeleen Watson

Reputation: 1

Update array using ngModel and ngFor

I am trying to read an array's values onto the form and then be able to update that same (toDos) array's values (so having name="todos{{i}}" within the <input> won't work because it makes it a string and not an array) The code right now only reads and updates the LAST index of the array.

my array is: toDos: string[] =["Todo1","Todo2","Todo3"]

my html is:

<div class="form-group" *ngFor="let todo of toDos; let i = index">
      <ul>
          <input class="form-control" name="toDo" [(ngModel)]="toDos[i]"  placeholder="To Do" style="border:none;">
      </ul>

</div>

Below is a screenshot of the current code and output. On submit I am printing the contents of toDos OG array and then the new updated content (which is only the last index)

HTML and Console Output

Upvotes: 0

Views: 2907

Answers (1)

Rob Monhemius
Rob Monhemius

Reputation: 5144

There seem to be several issues you are having.

1. [(ngModel)] is possibly used in a Form

Using [(ngModel)] in a form is what is causing only the last element to show up repeatably. There are special rules when you use ngModel in a Form

2. Updating one item refreshes the entire array

When you update an element in the array angular will by default replace the entire array. This would cause an issue where you can only enter 1 character and all inputs would be reloaded. You can bypass this by using a custom trackBy function, so angular knows you are only updating an element. Read more about the trackBy function.

Code

app.component.html

<div class="form-group" *ngFor="let todo of toDos; let i = index; trackBy: trackBy">
      <ul>
          <input class="form-control" name="toDo" [(ngModel)]="toDos[i]"  placeholder="To Do" style="border:none;">
      </ul>
</div>

app.component.ts

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  toDos: string[] =["Todo1","Todo2", "Todo3"]
  log(){
    console.log(this.toDos)
  }
  trackBy(index, item) {
    return index;
  }
}

Demo

Check out a Stackblitz demo

Upvotes: 2

Related Questions