Methods
|
transform
|
transform(query: string | undefined | null, ..._interpolationParameters: unknown[])
|
|
|
Parameters :
| Name |
Type |
Optional |
| query |
string | undefined | null
|
No
|
| _interpolationParameters |
unknown[]
|
No
|
|
import { PFE_LOGGER, PfeBusinessService } from '@allianz/ngx-pfe';
import { ChangeDetectorRef, inject, OnDestroy, Pipe, PipeTransform } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { merge } from 'rxjs';
import { take } from 'rxjs/operators';
import { PfeI18nFromStateHandler, REPLACEMENT_SEPARATOR } from '../pfe-i18n-from-state-handler';
@Pipe({
name: 'pfeI18nFromState',
pure: false, // required to update the value when the promise is resolved
standalone: false,
})
export class PfeI18nFromStatePipe implements PipeTransform, OnDestroy {
private translateService = inject(TranslateService);
private changeDetectorRef = inject(ChangeDetectorRef);
private pfeI18nFromStateHandler = new PfeI18nFromStateHandler(inject(PfeBusinessService), this.translateService, inject(PFE_LOGGER));
private value = '';
private lastKey: string | undefined;
private translationChangeSubscription = merge(
this.translateService.onTranslationChange,
this.translateService.onLangChange,
this.translateService.onFallbackLangChange
).subscribe(() => this.updateValue());
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
transform(query: string | undefined | null, ..._interpolationParameters: unknown[]): any {
if (!query) {
return query;
}
if (query !== this.lastKey) {
this.lastKey = query;
this.updateValue();
}
return this.value;
}
ngOnDestroy(): void {
this.translationChangeSubscription.unsubscribe();
this.pfeI18nFromStateHandler.destroy();
}
/**
* Translates the current key and subscribes to the state values used in it.
* The plain translation is used until the render with the state values is done. It is available right away
* when the translations are already loaded.
*/
private updateValue(): void {
const key = this.lastKey;
if (key) {
this.translateService
.get(key)
.pipe(take(1))
.subscribe((translation) => {
if (key === this.lastKey) {
this.value = translation;
}
});
this.pfeI18nFromStateHandler.initializeAndSubscribe(key, (translatedText: string) => this.renderText(key, translatedText));
}
}
/**
* Called by PfeI18nFromStateHandler when the key is changed/translated or when one of the used state values from
* the expression changes.
* The result is dropped if the key changed while rendering, so a slower render of a previous key can't overwrite it.
*/
private async renderText(key: string, translatedText: string): Promise<void> {
let result = '';
for (const textChunk of translatedText.split(REPLACEMENT_SEPARATOR)) {
const finalText = await this.pfeI18nFromStateHandler.getFinalText(textChunk);
result = result + finalText;
}
const value = result ? await this.translateService.get(result).toPromise() : '';
if (key !== this.lastKey) {
return;
}
this.value = value;
this.changeDetectorRef.markForCheck();
}
}