Is there a better way to push a value to a form control with an array as a value in Angular

Issue

I currently have a multi-select list that I want to add a value to from the component. The way I am doing it now doesn’t update on the UI and it doesn’t run my custom validator. If I console the value of the form control, it shows the correct value. Is there a better way to do this or can anyone explain why this is happening?

<mat-form-field appearance="fill">
  <mat-label>Toppings</mat-label>
  <mat-select [formControl]="toppings" multiple>
    <mat-option *ngFor="let topping of toppingList" [value]="topping">
      {{topping}}
    </mat-option>
  </mat-select>
</mat-form-field>
<br />
<button (click)="add()">Add Onion To List</button>
export class SelectMultipleExample {
      toppings = new FormControl([]);
      toppingList: string[] = [
        'Extra cheese',
        'Mushroom',
        'Onion',
        'Pepperoni',
        'Sausage',
        'Tomato',
      ];
    
      ngOnInit() {
        this.toppings.addValidators(this.validator);
      }
    
      add() {
        this.toppings.value.push('Onion');
        console.log(this.toppings.value);
      }
    
      validator(control: AbstractControl): ValidationErrors | null {
        console.log('Checked');
        return null;
      }

https://stackblitz.com/edit/angular-dwztco?file=src/app/select-multiple-example.ts

Solution

You need to call FormControl.setValue for it to be updated. FormControl.value is supposed to be read-only.

Change

this.toppings.value.push('Onion');

to

this.toppings.setValue([...this.toppings.value,"Onion"]);

Note that this add duplicated value "Onion" to the list when click the button multiple times, but the duplicates automatically get removed when you manually select something in the list. Anyway this is out of the scope of this question.

Answered By – Ricky Mo

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.