Reputation: 757
I'm trying to re-populate an input that uses a mat-autocomplete. However, whenever I send the value with this.optionForm.patchValue({selectedOption: 'my value'})
the results don't show in the GUI. If I console.log()
I can clearly see the value is set. I'm not sure if the issue has to do with the fact that I'm sometimes setting an object into the field and other times setting just a string? But I would like to be able to re-populate the input with results and display it appropriately. No matter how I try I can't seem to get the results to display.
Below is my component cut down to just the input in question and my Observable that is fetching results for the mat-autocomplete
. These work fine the first time the form is used.
// component.html
<mat-form-field>
<mat-label>Option Object</mat-label>
<input type="text" matInput formControlName="selectedOption" required
[matAutocomplete]="autoGroup">
<mat-autocomplete #autoGroup="matAutocomplete"
(optionSelected)="updateOptionInfo($event.option.value)"
[displayWith]="displayFn">
<mat-option *ngFor="let result of resultOptions | async" [value]="result">
<span>{{result}}</span>
</mat-option>
</mat-autocomplete>
// component.ts
this.resultOptions = this.optionForm.get('selectedOption').valueChanges
.pipe(
debounceTime(300),
switchMap(value => {
if (value === '') {
this.clearProviderInfo();
return of(null);
}
if (value !== '' && ((typeof value) !== 'object')) {
return this.optionService.fetchAndFilterOptions(value)
.pipe(
catchError((e) => {
console.error(e);
return of([]); // empty list on error
})
);
} else {
return of(null);
}
})
);
Any help would be appreciated!
Upvotes: 0
Views: 4141
Reputation: 757
I've created a stackblitz to reproduce the issue:
https://stackblitz.com/edit/material-6-gh3rmt?file=app/app.component.ts
In doing so I realize what the issue was! By having a display function returning some property of the object, it obviously displays empty for a string. So the object is being set and can be seen in the form, but because I've used a custom display function it is run over by the null property on the string.
Hopefully I can help other people that may run into this issue in the future!
To flesh out this solution:
displayFn(x) {
return x.name; // if name doesn't exist this will obviously return null!
}
So a fix is to have a backup in the case that what is being selected isn't an object with the .name
property:
if ((typeof x) === 'string') {
return x;
}
return x ? x.name : undefined;
Upvotes: 4
Reputation: 2539
Approach 1:
Use setTimeout
to achieve the desired result, use as following -
setTimeout(()=>{
this.optionForm.patchValue({selectedOption: 'test'});
}, 0);
Approach 2 :
This approach works without async
//-----in component.html file, without async-------
*ngFor="let result of resultOptions"
// -------in component.ts file---------
this.optionForm.get('selectedOption').valueChanges
.pipe(
debounceTime(300),
switchMap(value => {
if (value === '') {
this.clearInfo();
return of(null);
}
if (value !== '' && ((typeof value) !== 'object')) {
return of(this.pretendOptions);
} else {
return of(null);
}
})
).subscribe(e=>this.resultOptions = e);
//--- value is updated after subscribing to the `valueChanges`.
this.optionForm.patchValue({selectedOption: 'test'});
Upvotes: 2