Reputation: 8863
Data displayed on HTML template is Key form data. Meaning, it needs to be translated. For that purpose, I would like to call an Async function from my template. Tried this, with no success:
Template:
<span class="myClass-rowValue">{{translateServingStyle(size.defaultServingStyle?.surcharge) | async}}</span>
Component ts file:
servingStylesData$: Observable<ServingStyles_servingStyles[]>;
ngOnInit(): void {
this.servingStylesData$ = of(this._apollo
.watchQuery<ServingStyles>({
query: ServingStylesQuery
}))
.pipe(
filter((query) => !!query),
switchMap((query) => query.valueChanges),
take(1),
takeUntil(this._ngOnDestroy),
map((response) => response.data.servingStyles)
);
}
translateServingStyle(servingStyleValue: string): Observable<string> {
return this.servingStylesData$
.pipe(
map((servingStyles) => servingStyles
.filter((servingStyle) => servingStyle.value === servingStyleValue)
.map((selectedServingStyle) => selectedServingStyle.value)[0]
)
);
}
What is the currect why of doing this?
# Edit
This is making my browser crash. Getting into an endless loop calling translateServingStyle()
I have tried removing my function code, and just returning
of("some string")
and it works fine.
But when referencing a Pipe to a local Variable, this loop happens. Can anyone please explain why?
Upvotes: 3
Views: 3958
Reputation: 2098
tl;dr
Don't use the async pipe with function calls. This is expensive and long-running and can destroy the user experience or in your case crash your browser: Manage your observables yourself and not with the easy to use async
pipe.
If you still want to use the async
pipe with a function, you can try using the ChangeDetectionStrategy.OnPush. This comes with other downsides, such as running the change detection manually, e.g. with this.cdr.detectChanges();
and cdr
being of type ChangeDetectorRef
.
Please be aware of how Angulars Lifecycle system works.
Since evaluated function values do not have an internal reference (which Angular uses to check whether values have changed or need to be updated), they won't be checked by the lifecycle hook ngOnChanges
, but rather with ngDoCheck
, which runs a lot of times.
This is especially bad with pipes, and the worst with the async pipe. If we call your usage of async
pipes expensive and long running, Angular states, that:
An expensive and long-running pipe could destroy the user experience
or in your case crash the browser.
Please find this blog post for further explanation.
Upvotes: 5