3

In an Angular html template I have an select element with mat-select directive (Angular Material) which loads data from an object stored in a property called "selectedCriteria" in a service .ts file. Three types of object can be stored in the "selectedCriteria" property based on application logic and all of them have "name" variable of type String. So I want to load the object name in this select element.

Problem is when the app loads, the select element does not load/show the "selectedCriteria" because it's an object and not a string. I can use selectedCriteria.name to bind it with a string value, but that will add additional code to convert from object to string and vice versa for two way data binding. What is the solution to load an object in this select element during app startup?

<mat-form-field style="width: 45%; display: inline-block">
    <mat-select
        placeholder="Criteria"
        [(value)]="reportService.selectedCriteria"
        (valueChange)="reportService.filterSalesData()"
    >
        <mat-option
            *ngFor="let criteria of reportService.criteriaList"
            [value]="criteria"
            >{{ criteria.name }}</mat-option
        >
    </mat-select>
</mat-form-field>
3
  • Can you add stackblitz.com demo what you need to do Commented Feb 23, 2019 at 22:49
  • Here it is. I have simplified the example with just a user object. All I want to do is to load the user.name in the mat select but I want the selectedUser property to have a type of user and not string. stackblitz.com/edit/angular-wlca8k Commented Feb 23, 2019 at 23:08
  • found a related question: stackoverflow.com/a/53499257/6908282 Commented Apr 24 at 13:46

1 Answer 1

6

You can do this as below.

HTML

 <mat-form-field style="width: 45%; display: inline-block; margin-right: 40px;">
  <mat-select [(ngModel)]="selectedCriteria" (selectionChange)="onSelectValueChange()">
    <mat-option *ngFor="let criteria of criteriaList" [value]="criteria">{{criteria.name}}</mat-option>
  </mat-select>
</mat-form-field>

TS

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
selectedCriteria: User;
criteriaList: User[] = [
  { name: 'John Doe'},
  { name: 'Albert Einstein'},
  { name: 'Isaac Newton'}
];


ngOnInit(){
  this.selectedCriteria = this.criteriaList[0];
}

onSelectValueChange () {
  console.log(this.selectedCriteria);
  console.log('Type of Selection => ', typeof this.selectedCriteria);
}
}

interface User{
  name: string;
}

StackBlitz Example

Sign up to request clarification or add additional context in comments.

3 Comments

thanks for your answer but my problem was somewhere else and I fixed it. My solution to the problem raised an interesting observation. Please go to this stackBlitz example stackblitz.com/edit/angular-mat-select-problem. I set the selectedCriteria based on a filtering search on the criteriaList with a currentUser object. In the example app.component.ts file, please see that in line 24 --- this.selectedCriteria = this.currentUser doesn't work but line 25 --- // this.selectedCriteria = criteria; works, even though they are exactly the same object
It seems like if I don't set the selectedCriteria object from the criteriaList array it doesn't work even though this.currentUser is the exact same User object. Why do you think that's the case? –
I think I gave the answer what you ask. There is no magic in this.selectedCriteria = this.currentUser and this.selectedCriteria = criteria; That is basic javascript every javascript programmer should know.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.