Reputation: 113
I'm trying to populate a material select dropdown with values from a remote API service. I keep getting a null or undefined value at the component.
This is for Angular 7 using the MEAN stack and Angular Material. I've tried compareWith function and logging the values. I noticed that the component is always loading its value first which is null, then the API service which has values.
<mat-form-field>
<mat-select formControlName="company" placeholder="Select
Company" [(value)]="selectedCompany" [compareWith]="compareFn">
<mat-option *ngFor="let lC of loadedCompanies"
[value]="lC.id">
{{lC.name}}
</mat-option>
</mat-select>
</mat-form-field>
ngOnInit() {
this.authStatusSub = this.authService
.getAuthStatusListener()
.subscribe(authStatus => {
this.isLoading = false;
});
this.form = new FormGroup({
id: new FormControl(null),
company: new FormControl(this.loadedCompanies)
});
this.companyService.getCompanyList();
this.companySub = this.companyService
.getcompanyUpdateListener()
.subscribe((companyData: {companies: Company[]}) => {
this.isLoading = false;
this.loadedCompanies = companyData.companies;
});
}
compareFn(c1: Company, c2: Company): boolean {
return c1 && c2 ? c1.id === c2.id : c1 === c2;
}
I would expect the values to load from the observable and populate the select input before loading the component.
Upvotes: 6
Views: 7149
Reputation: 42606
You can add an *ngIf
to the parent container such that the mat-select component will not be loaded until the observable has been subscribed and loadedCompanies
has been assigned.
<mat-form-field *ngIf = "loadedCompanies">
<mat-select formControlName="company" placeholder="Select
Company" [(value)]="selectedCompany" [compareWith]="compareFn">
<mat-option *ngFor="let lC of loadedCompanies"
[value]="lC.id">
{{lC.name}}
</mat-option>
</mat-select>
</mat-form-field>
The FormControl company should be set with an initial value of null, and not the entire loadedCompanies
array.
this.form = new FormGroup({
id: new FormControl(null),
company: new FormControl(null)
});
This is how you should populate your loadedCompanies
array.
loadedCompanies: Company[];
ngOnInit() {
.
.
// other lines of code before this
this.companyService.getCompanyList().subscribe(companyData => {
this.loadedCompanies = companyData.companies;
});
}
Upvotes: 8