Angular 6 Material <mat-select> multiple set default value using form control
Asked Answered
W

5

11

I am using form control here is code for my html component

<mat-form-field>
  <mat-select placeholder="Toppings" [formControl]="toppings" multiple>
    <mat-option *ngFor="let topping of toppingList" [value]="topping">{{topping.value}}</mat-option>
  </mat-select>
</mat-form-field>

And my ts file is

export class SelectMultipleExample {
   toppings = new FormControl();
  toppingList: any[] = [
      { id:1,value:"test 1"},
      { id:2,value:"test 2"},
      { id:3,value:"test 4"},
      { id:4,value:"test 5"},
      { id:5,value:"test 6"},
      { id:6,value:"test 7"}
    ];

  

  constructor(){
    this.bindData();
  }

  bindData(){
    const anotherList:any[]=[
      { id:1,value:"test 1"},
      { id:2,value:"test 2"}
      ]

      this.toppings.setValue(anotherList)
  }
}

I want to set default value for mat select , any help how to achieve this will be great. I want to set multiple default value.

Wordsmith answered 26/7, 2018 at 15:43 Comment(0)
A
15

The problem is due to the fact that your options are objects. In order for the selections to be applied, the selected objects must be the same objects as the ones used for the options. Revise your code as follows:

export class SelectMultipleExample {
    toppings = new FormControl();
    toppingList: any[] = [
        { id:1,value:"test 1"},
        { id:2,value:"test 2"},
        { id:3,value:"test 4"},
        { id:4,value:"test 5"},
        { id:5,value:"test 6"},
        { id:6,value:"test 7"}
    ];

    constructor(){
        this.bindData();
    }

    bindData() {
        const anotherList: any[] = [
            this.toppingList[0],
            this.toppingList[1]
        ]

        this.toppings.setValue(anotherList)
    }
}
Ajar answered 26/7, 2018 at 16:26 Comment(4)
Can you please provide HTML also because it's a bit confusing.Franciskus
No change to the HTML - use the original.Ajar
@G.Tranter i am populating list with api data because i am binding toppingList on ngInit so, when i get toppingList[0] and toppingList[1] in bindData() than i am getting error property undefined.Chanellechaney
bindData() is called from the constructor, which runs before ngOnInit(). Try calling bindData() after you data has been populated.Ajar
D
2
 <mat-form-field>
 <mat-label>Select Global Markets</mat-label>
 <mat-select [formControl]="globalmarketCategory" multiple >
 <mat-option *ngFor="let list of toppingList" [value]="list">{{list.value}}</mat-option>
 </mat-select>

export class SelectMultipleExample {
    globalmarketCategory= new FormControl();
    toppingList: any[] = [
                        { id:1,value:"test 1"},
                        { id:2,value:"test 2"},
                        { id:3,value:"test 4"},
                        { id:4,value:"test 5"},
                        { id:5,value:"test 6"},
                        { id:6,value:"test 7"}
                        ];


    list = []
    constructor(){
        const anotherList:any[]=[  
                                { id:1,value:"test 1"},
                                { id:2,value:"test 2"}
                                ]
        this.globalmarketCategory.setValue(anotherList);
    }
}
Delmore answered 26/9, 2019 at 5:32 Comment(2)
@palani also add description what is difference in your code with the accepted onceWordsmith
I have included both ui and typescript, it's working fine.Delmore
V
0

You may use compareWith attribute of mat-select. See that answer https://mcmap.net/q/817380/-use-comparewith-function-from-angular-material-mat-select-component-with-linked-firebase-value

Vanvanadate answered 10/10, 2019 at 13:51 Comment(0)
B
0

Use compareWith function while using multiple.

so HTML will look like

 <mat-form-field>
  <mat-select
    [compareWith]="compareFn"
    [(ngModel)]="theArrayofSelectedValues">
       <mat-option  *ngFor="let obj of listOfObjs" [value]="obj">
          {{ obj.name }}
       </mat-option>
    </mat-select>
</mat-form-field>

and in TS compareFn

compareFn(o1: any, o2: any) {
  if(o1.id == o2.id )
  return true;

}
Briar answered 6/9, 2021 at 7:51 Comment(0)
O
0

The answer given by G. Tranter gave the correct answer.

Based on their answer, I created the following more detailed example (which might be closer to a real-world implementation of this functionality):

toppings.html:

<mat-form-field>
  <mat-label>Select Your Favorite Topping(s)</mat-label>
  <mat-select placeholder="Select Topping(s)" [formControl]="ToppingsControl" required multiple>
    <mat-option *ngFor="let t of AllToppings" [value]="t">{{t.Name}}</mat-option>
  </mat-select>
</mat-form-field>

toppings.ts:

import { Component } from '@angular/core';
import { FormControl, Validators } from '@angular/forms';
import ITopping from 'src/app/interfaces/topping-dto';

@Component({
  selector: 'toppings',
  templateUrl: './toppings.html',
  styleUrls: ['./toppings.css']
})
export default class SelectMultipleExample {

  protected ToppingsControl: FormControl<Array<ITopping>> = new FormControl(null, Validators.required);
  protected AllToppings: Array<ITopping> = [];

  public constructor() {

    // These values can be injected, pulled from a database, etc.
    this.AllToppings.push({ Id: 1, Name: 'Sprinkles' });
    this.AllToppings.push({ Id: 2, Name: 'Hot Fudge' });
    this.AllToppings.push({ Id: 3, Name: 'Whipped Cream' });
    this.AllToppings.push({ Id: 4, Name: 'Crushed Nuts' });
    this.AllToppings.push({ Id: 5, Name: 'Maraschino Cherries' });

    // Get a reference to the objects that are initially selected by default
    let selectedToppings: Array<ITopping> = [
      this.AllToppings[0],
      this.AllToppings[1]
    ];

    // Set the value of the control to be the selected objects
    this.ToppingsControl.setValue(selectedToppings);
  }

}

topping-dto.ts:

interface ITopping {
  Id: number,
  Name: string
}
export default IClientDto;
Occultation answered 14/11, 2023 at 0:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.