122

I have a simple select option form field in my Angular material project:

component.html

<mat-form-field>
    <mat-select [(value)]="modeSelect" placeholder="Mode">
        <mat-option value="domain">Domain</mat-option>
        <mat-option value="exact">Exact</mat-option>
    </mat-select>
</mat-form-field>

Where [(value)]="modeSelect" is binded to the modeSelect property in the component.ts file

I want to make it so the <mat-option value="domain">Domain</mat-option> is selected by default on page load.

ng-selected did not work for me

upe
  • 1,862
  • 1
  • 19
  • 33
cup_of
  • 6,397
  • 9
  • 47
  • 94

19 Answers19

163

Working StackBlitz

No need to use ngModel or Forms

In your html:

<mat-form-field>
    <mat-select [(value)]="selected" placeholder="Mode">
        <mat-option value="domain">Domain</mat-option>
        <mat-option value="exact">Exact</mat-option>
    </mat-select>
</mat-form-field>

and in your component just set your public property selected to the default:

selected = 'domain';

upe
  • 1,862
  • 1
  • 19
  • 33
Narm
  • 10,677
  • 5
  • 41
  • 54
  • hello! thanks for the answer, this is what i got when i tried it: Can't bind to 'selected' since it isn't a known property of 'mat-option'. – cup_of Jun 01 '18 at 21:13
  • ah seems to work in your example, but not for mine. is there a particular module i need to import in my appmodule.ts? – cup_of Jun 01 '18 at 21:29
  • What version of Angular and Angular Material are you using? – Narm Jun 01 '18 at 21:31
  • angular material 6.2.0 and angular 6.0.3 – cup_of Jun 01 '18 at 21:33
  • All you need to import in your module for this example is `import {MatSelectModule} from '@angular/material';`. Do you have that? – Narm Jun 01 '18 at 21:36
  • yup I have that. anyway i got it working now! thank you – cup_of Jun 01 '18 at 21:38
  • 2
    How to do this for multi select? I tried with this and its not working .ts file: selected = ['domain,exact']; – aswininayak Oct 15 '18 at 20:04
  • @Narm this is not the proper way to do two way binding. – Irrfan23 Nov 24 '19 at 08:56
  • 11
    This doesn't work for me. Nothing I put into the `[(value)]` attribute shows up in the `mat-select`. – ChumiestBucket Dec 04 '19 at 21:46
  • 3
    This almost worked for me, it was setting the selected value, but it was not initializing the form control to display the correct value visually on load. In the .ts file I also had to add to ngOnInit(): `this.myForm.controls.myControl.setValue("defaultValue")` – Emilie Dec 22 '19 at 20:53
  • 4
    Just for information, you need to make sure the datatype of the default value matches with that of the options, for.eg, {{ hero.name }} will work. But if you assign a string type to [(value)] it wont work. – Subbu Mar 30 '20 at 08:00
  • @Subbu Thank you so much for pointing out the dataType issue. i've wasted 3 hours for this. Also i had to call setValue(). – romal tandel Aug 13 '20 at 12:42
  • @romaltandel, Most welcome and I am glad it helped :) – Subbu Aug 13 '20 at 18:45
  • I have a reusable component that I am trying to set the default to and I do not know a value that will be default as the options change depending on the input. So I cannot do selected = 'some value' in my component.
    {{ enumType }} {{car}}
    In my component, I am not sure how should this be handled or how to call setValue() as I am not using the form.
    – Nick Mar 05 '21 at 19:43
  • i am trying to add value with ngmodel(ngmodel for onchange select value -api call), but its not wokring – VISHAL SINGH Jul 02 '21 at 11:08
  • Make sure the selected value is of type "string" and not of type "number". – Carli Beeli Dec 06 '21 at 20:34
  • Anyone coming to this page trying to use objects for [(value)] has to pass a function to `mat-select`'s [compareWith] input as described in https://stackoverflow.com/questions/47333171/angular-material-mat-select-not-selecting-default – NoBullsh1t Jun 08 '22 at 03:54
34

This issue vexed me for some time. I was using reactive forms and I fixed it using this method. PS. Using Angular 9 and Material 9.

In the "ngOnInit" lifecycle hook

  1. Get the object you want to set as the default from your array or object literal
const countryDefault = this.countries.find(c => c.number === '826');

Here I am grabbing the United Kingdom object from my countries array.

  1. Then set the formsbuilder object (the mat-select) with the default value.
this.addressForm.get('country').setValue(countryDefault.name);
  1. Lastly...set the bound value property. In my case I want the name value.
<mat-select formControlName="country">
    <mat-option *ngFor="let country of countries" [value]="country.name" >
        {{country.name}}
    </mat-option>
</mat-select>

Works like a charm. I hope it helps

upe
  • 1,862
  • 1
  • 19
  • 33
Darren Street
  • 1,652
  • 17
  • 21
  • This is the one that works with angular 9 or greater. Thank you!!! – vijayakumarpsg587 Nov 30 '20 at 16:40
  • This can be solved more easily by two-way-binding [(value)] to `mat-select` and also passing a [compareWith] function that returns a boolean when both passed arguments match to `mat-select`, see https://stackoverflow.com/questions/47333171/angular-material-mat-select-not-selecting-default – NoBullsh1t Jun 08 '22 at 03:57
27

Try this

<mat-form-field>
    <mat-select [(ngModel)]="modeselect" [placeholder]="modeselect">
        <mat-option value="domain">Domain</mat-option>
        <mat-option value="exact">Exact</mat-option>
    </mat-select>
</mat-form-field>

Component:

export class SelectValueBindingExample {
    public modeselect = 'Domain';
}

Live demo

Also, don't forget to import FormsModule in your app.module

upe
  • 1,862
  • 1
  • 19
  • 33
Vikas
  • 11,859
  • 7
  • 45
  • 69
  • Hello this makes the property modeselect = 'domain' but it does not seem to select the domain option by default – cup_of Jun 01 '18 at 21:25
  • 2
    I Have updated my answer kindly check the working stackblitz – Vikas Jun 01 '18 at 21:28
  • Hello Vikas there is dynamic values in *ngFor that time how to show using id? – Dharmesh Sep 12 '18 at 11:38
  • @AmishaRana Did you mean how to show default value if data is dynamic?? – Vikas Sep 12 '18 at 12:34
  • 2
    @AmishaRana Have a look at this [stackblitz](https://stackblitz.com/edit/angular-xsnncp) – Vikas Sep 12 '18 at 12:45
  • This helped me realize that in my case what was happening is that mat-select is treating null as "no selection" even if null is one of the list values. In essence "placeholder" means "text to show when null". – Steve In CO Dec 20 '21 at 19:06
9

I would like to add to Narm's answer here and have added the same as a comment under her answer.

Basically the datatype of the value assigned to [(value)] should match the datatype of the [value] attribute used for the mat-options. Especially if some one populates the options using an *ngFor as below

<mat-form-field fxHide.gt-sm='true'>
    <mat-select [(value)]="heroes[0].id">
        <mat-option *ngFor="let hero of heroes" [value]="hero.id">{{ hero.name }}</mat-option>
    </mat-select>
</mat-form-field>

Notice that, if you change the [(value)]="heroes[0].id" to [(value)]="heroes[0].name" it won't work as the data types don't match.

These are my findings, please feel free to correct me if needed.

upe
  • 1,862
  • 1
  • 19
  • 33
Subbu
  • 588
  • 1
  • 7
  • 18
  • Problem with this is if heroes does not contain any data "yet" it will throw an error – Jnr May 31 '21 at 09:12
  • If an array or dictionary doesn't contain any values but is used with an index as above it is expected to throw an error typically "Index out of bounds" or something similar and that is an expected behavior. Are you getting an error? if yes what is the error? – Subbu Jun 11 '21 at 09:52
  • If your `heroes` data source came from a server, you would get an error. It's not an index out of range error because there is no `id` in `heroes`. If you regard it as irrelevant but true, just ignore it and don't downvote it because it might help someone else . – Jnr Jun 11 '21 at 13:45
  • For your info, I have just commented to gain more clarity on your issue (Are you getting an error? if yes what is the error?). Also if there is an error in the response returned by a server typically in response to an api call, it should be taken care by sanity checks and appropriate actions should be taken in the service layer and UI should display appropriate messages. Haven't down voted it and don't intend to. Please always double check before you state such comments. – Subbu Jun 11 '21 at 14:41
  • My apologies. So, in your scenario there would simply be an error on the client side because the `heroes` object does not have any data if it comes from a server. The view is trying to render `heroes` but it's still waiting for the server response. – Jnr Jun 12 '21 at 07:27
9

Using Form Model (Reactive Forms)

--- HTML code ---

<form [formGroup]="patientCategory">
<mat-form-field class="full-width">
    <mat-select placeholder="Category" formControlName="patientCategory">
        <mat-option>--</mat-option>
        <mat-option *ngFor="let category of patientCategories" [value]="category">
            {{category.name}} 
        </mat-option>
    </mat-select>
</mat-form-field>

--- ts code ---

ngOnInit() {
    this.patientCategory = this.fb.group({
        patientCategory: [null, Validators.required]
    });

    const toSelect = "Your Default Value";
    this.patientCategory.get('patientCategory').setValue(toSelect);
}

Without form Model

--- HTML code ---

<mat-form-field>
  <mat-label>Select an option</mat-label>
  <mat-select [(value)]="selected">
    <mat-option>None</mat-option>
    <mat-option value="option1">Option 1</mat-option>
    <mat-option value="option2">Option 2</mat-option>
    <mat-option value="option3">Option 3</mat-option>
  </mat-select>
</mat-form-field>

--- ts code ---

selected = 'option1';

Here take care about type of the value assigning

upe
  • 1,862
  • 1
  • 19
  • 33
Satish babu
  • 100
  • 1
  • 2
3

I was able to set the default value or whatever value using the following:

Template:

<mat-form-field>
    <mat-label>Holiday Destination</mat-label>
    <mat-select [(ngModel)]="selectedCity" formControlName="cityHoliday">
        <mat-option [value]="nyc">New York</mat-option>
        <mat-option [value]="london">London</mat-option>
        <mat-option [value]="india">Delhi</mat-option>
        <mat-option [value]="Oslo">Oslo</mat-option>
    </mat-select>
</mat-form-field>

Component:

export class WhateverComponent implements OnInit {

    selectedCity: string;

    ngOnInit() {
        this.selectedCity = 'london';
    } 
}
upe
  • 1,862
  • 1
  • 19
  • 33
meol
  • 1,027
  • 11
  • 7
2

Try this:

<mat-select [(ngModel)]="defaultValue">
export class AppComponent {
    defaultValue = 'domain';
}
upe
  • 1,862
  • 1
  • 19
  • 33
yer
  • 1,454
  • 2
  • 16
  • 33
  • hello I am getting this error when i try your answer: Error: If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions. – cup_of Jun 01 '18 at 21:15
  • are you having mat-form-field ? – yer Jun 01 '18 at 21:18
2

On your typescript file, just assign this domain on modeSelect on your ngOnInit() method like below:

ngOnInit() {
    this.modeSelect = "domain";
}

And on your html, use your select list.

<mat-form-field>
    <mat-select  [(value)]="modeSelect" placeholder="Mode">
        <mat-option value="domain">Domain</mat-option>
        <mat-option value="exact">Exact</mat-option>
    </mat-select>
</mat-form-field>
upe
  • 1,862
  • 1
  • 19
  • 33
Abdus Salam Azad
  • 5,087
  • 46
  • 35
1

Read this if you are populating your mat-select asyncronously via an http request.

If you are using a service to make an api call to return the mat-select options values, you must set the 'selected value' on your form control as part of the 'complete' section of your service api call subscribe().

For example:

this.customerService.getCustomers().subscribe(
customers => this.customers = customers ,
error => this.errorMessage = error as any,
() => this.customerSelectControl.setValue(this.mySelectedValue));
upe
  • 1,862
  • 1
  • 19
  • 33
1

Here is the solution

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

interface Food {
    value: string;
    viewValue: string;
}

interface Car {
    value: string;
    viewValue: string;
}

/**
 * @title Basic select with initial value and no form
 */
@Component({
    selector: 'select-initial-value-example',
    templateUrl: 'select-initial-value-example.html',
})
export class SelectInitialValueExample {
    foods: Food[] = [
        { value: 'steak-0', viewValue: 'Steak' },
        { value: 'pizza-1', viewValue: 'Pizza' },
        { value: 'tacos-2', viewValue: 'Tacos' }
    ];
    cars: Car[] = [
        { value: 'ford', viewValue: 'Ford' },
        { value: 'chevrolet', viewValue: 'Chevrolet' },
        { value: 'dodge', viewValue: 'Dodge' }
    ];
    selectedFood = this.foods[2].value;
    selectedCar = this.cars[0].value;

    selectCar(event: Event) {
        this.selectedCar = (event.target as HTMLSelectElement).value;
    }
}

In template use it lie this

<h4>Basic mat-select with initial value</h4>
<mat-form-field appearance="fill">
    <mat-label>Favorite Food</mat-label>
    <mat-select [(value)]="selectedFood">
        <mat-option></mat-option>
        <mat-option [value]="option.value" *ngFor="let option of foods">{{ option.viewValue }}</mat-option>
    </mat-select>
</mat-form-field>
<p>You selected: {{selectedFood}}</p>

<h4>Basic native select with initial value</h4>
<mat-form-field appearance="fill">
    <mat-label>Favorite Car</mat-label>
    <select matNativeControl (change)="selectCar($event)">
        <option value=""></option>
        <option *ngFor="let option of cars" [value]="option.value" [selected]="selectedCar === option.value">{{
            option.viewValue }}</option>
    </select>
</mat-form-field>
<p>You selected: {{selectedCar}}</p>
upe
  • 1,862
  • 1
  • 19
  • 33
Zia Khan
  • 188
  • 2
  • 9
1

I will post another answer to this post for people who don't have a simple string, but an object which they want their users to select. Simply bind the object to mat-selects [(value)] and also pass a [compareWith] function like so:

<mat-form-field>
  <mat-select [(value)]="selectedCountry" [compareWith]="isSameCountry">
     <mat-option *ngFor="let country of countries"
                 [value]="country">{{ country.name }}</mat-option>
  </mat-select>
</mat-form-field>
public isSameCountry(countryA?: Country, countryB?: Country): boolean {
  return !!countryA && countryA.isoCode === countryB?.isoCode;
}

No need to deal with the form object then.

Reference: Angular Material: mat-select not selecting default

NoBullsh1t
  • 483
  • 4
  • 14
1

<mat-select [(ngModel)]="modeSelect" placeholder="Mode">
  <mat-option selected value="" disabled>Default value</mat-option>
  <mat-option *ngFor="let obj of Array"  [value]="obj.value">{{obj.value}}</mat-option>
</mat-select>
Rohit
  • 101
  • 7
0

Normally you are going to do this in your template with FormGroup, Reactive Forms, etc...

this.myForm = this.fb.group({
    title: ['', Validators.required],
    description: ['', Validators.required],
    isPublished: ['false',Validators.required]
});
upe
  • 1,862
  • 1
  • 19
  • 33
Jonathan
  • 3,893
  • 5
  • 46
  • 77
0

HTML :

<mat-select [(ngModel)]="currentCompany" placeholder="All" (selectionChange)="selectionChange($event.value)">
    <mat-option>All</mat-option>
    <mat-option *ngFor="let company of logsCompanies" [value]="company">
        {{company}}
    </mat-option>
</mat-select>

TS : Filter by company name; If the selected data is 'All', it returns undefined and if it is undefined, I return all the data.

selectionChange(e: any)
{
    if (e == undefined) {
        this.dataSource.data = this.allDataSource;
    }
    else {
        this.logDataSource.data = this.allDataSource;
        this.logDataSource.data = this.logDataSource.data.filter(x => x.companyName == e);
    }
}
upe
  • 1,862
  • 1
  • 19
  • 33
0

In order to set default value for mat-select drop down use the below method using reactive form in angular.

HTML

<mat-select[(value)]="selectedId" [formControl]="foodId">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{food.name}}
    </mat-option>
</mat-select>

TS file

foodId = new FormControl(foods[0].value); // to set the first element as default

FYI - Based on the requirement you can change the value
Praveen G
  • 161
  • 1
  • 2
  • 8
0

You can use ngModel to link them like so, it just needs to be linked to the actual value...

<mat-form-field>
    <mat-select [(ngModel)]="domain" placeholder="Mode">
      <mat-option value="domain">Domain</mat-option>
      <mat-option value="exact">Exact</mat-option>
    </mat-select>
</mat-form-field>
Ken Mbira
  • 41
  • 1
  • 4
0

The Most Simple Example to Clarify this without needing to bind to any values from component.ts and directly bind to HTML option value goes like this:

<mat-form-field class="d-block mt-2" appearance="outline">
    <mat-select #year disabled [value]="default.value">
        <mat-option #default selected value="default.value">2023</mat-option> 
    </mat-select>
</mat-form-field>
André
  • 1,602
  • 2
  • 12
  • 26
-1

HTML

<mat-form-field>
<mat-select [(ngModel)]="modeSelect" placeholder="Mode">
  <mat-option *ngFor="let obj of Array"  [value]="obj.value">{{obj.value}}</mat-option>
</mat-select>

Now set your default value to

modeSelect

, where you are getting the values in Array variable.

Irrfan23
  • 362
  • 5
  • 17
-1

It took me several hours to figure out this until the similarity of the datatypes between the array and that of the default value worked for me...