I am using [displayWith] directive in my mat-autocomplete. It works fine when i am manually selecting values but when i reload the page i am not getting translation. Parameter necessary for translation is asynchronously loaded from query params in ngOnInit. So I rely on async parameter but my displayFunction() is sync function. How to resolve that?
Without [displayWith] function everything is working OK but without translation (it's just displaying pure values what i do not want). So i am sure that rest of the code is proper.
My mat-autocomplete:
<mat-form-field [formGroup]="cityForm"
appearance="outline"
floatLabel="never"
color="primary">
<mat-icon matPrefix>location_on</mat-icon>
<input type="text" placeholder="{{ 'job_offer_search_bar.job-offer-search-bar-city-form.placeholder' | translate }}"
aria-label="Number" matInput
formControlName="cityControl" [matAutocomplete]="auto">
<mat-autocomplete #auto="matAutocomplete" (optionSelected)="onSelectionChanged($event.option.value)"
[displayWith]="displayFn.bind(this)">
<mat-option>
{{ 'job_offer_search_bar.job-offer-search-bar-city-form.all' | translate }}
</mat-option>
<mat-option *ngFor="let city of filtredCities | async" [value]="city">
{{ 'job_offer_search_bar.job-offer-search-bar-city-form.city' | translate:"{ city: '" + city +"' }"}}
</mat-option>
</mat-autocomplete>
</mat-form-field>
My displayWith function is below:
displayFn(val: string){
if (!val) return '';
let stringToReturn;
this.translate.get('job_offer_search_bar.job-offer-search-bar-city-form.city', {city: val}).subscribe(value => {
console.log('inside subscribe', value);
stringToReturn = value;
});
console.log('after sub', stringToReturn);
if (stringToReturn != undefined) {
return stringToReturn;
} else {
return 'Sorry, value has not been translated';
}
Console.log in subscribe
is invoked after console.log after subscribe
. So subscribe is made after i get my parameter for translation, so after my return...
I need some trick or tip to pass my translated string as a return.
I assume that there is a way to do that. Any help will be appreaciated.
Observables are, at the most cases, async functions.
Depending on your implementation you may use translate.instant
displayFn(val: string) {
const defaultMessage = 'Sorry, value has not been translated';
return val
? this.translate.instant('job_offer_search_bar.job-offer-search-bar-city-form.city', { city: val }) || defaultMessage
: '';
}
If the instant function is called before the translation file is loaded, it will return undefined.
EDIT:
displayFn(val: string) {
const translate$ = this.translate.get('job_offer_search_bar.job-offer-search-bar-city-form.city', { city: val }).pipe(
map(translatedText => translatedText || 'Sorry, value has not been translated')
)
return val
? translate$
: of('');
}
[displayWith]="displayFn.bind(this) | async"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With