I have code in my ngOnInit
to get the translation for some particular text. It calls the following function:
async getEmailTranslation() {
const email$ = this.translate.get('SUPPORT_TRANSLATE.EMAIL');
this.email = await firstValueFrom(email$);
console.log(this.email);
console.log(typeof this.email);
}
When I check the console, I am seeing "Email" and "string" returned from the two console.log()
statements, which is exactly what I am expecting.
In the template, when I render {{ this.email }}
, the template shows [object Object]
instead of the string.
email
is defined as:
email: string;
What am I missing?
The strange thing is with another translation, this is working as expected:
async getWebsiteTranslation() {
const website$ = this.translate.get('SUPPORT_TRANSLATE.WEBSITE');
this.website = await firstValueFrom(website$);
}
In this case, when displaying {{ this.website }}
in the template, it is properly rendering the string I am expecting.
CodePudding user response:
You're probably coming from a different framework where Promises are used. You could solve your problem with Promises for sure, but Angular is pretty strongly opinionated towards Observables (from RxJS).
Observables are like Promises in the sense that they are used to handle asynchronous operations, but they have a few key differences, probably the most important of which are that Observables don't run "automatically" if you don't subscribe to them (unlike Promises which run even if you don't call .then()
or await
), and that Observables can emit more than one value before they are done.
Here, the "Angular way" to do things is to:
Expose a public Observable to your html. Currently you're trying to expose
public email: string
, but it would be better to expose thepublic email$: Observable<string>
directly.Then, in your template, use the
async
pipe to get the value of your email.
The html may look something like
<div *ngIf="email$ | async as email">
My email is {{ email }}.
</div>
The *ngIf
allows two things: first off, the div won't be shown until email$
has emitted its first value, so you'll never see a div with just "My email is ." or "My email is [null]." here. Second, using the "as" syntax, it creates a variable called email
, whose value is whatever email$
emitted, available inside the div
where the *ngIf
is declared.