I would like to use Transloco and gather translations from existing REST API and not from the i18n file. I replaced line in TranslocoHttpLoader by rest service call:
getTranslation(lang: string): Observable<Translation> {
// return this.http.get<Translation>(`/assets/i18n/${lang}.json`);
return this.translationService.fetchTranslations();
}
Where Translation
is Transloco type:
export declare type Translation = HashMap;
export declare type HashMap<T = any> = {
[key: string]: T;
};
Translation REST API is returning:
{
"languageKeys": [
{
"key": "hello",
"value": "hello transloco"
},
...
]
}
So
export class TranslationRest {
languageKeys: LanguageKeyRest[] = [];
}
export class LanguageKeyRest {
constructor(public key: string, public value: string) {}
}
So I need "convert" Observable<TranslationRest>
into Observable<Translation>
consumed by Transloco:
TranslationService
public fetchTranslations(): Observable<Translation> {
const response: Observable<TranslationRest> = this.httpClient.post<TranslationRest>(this.url, this.body, {'headers': this.headers});
return this.convert1(response);
}
This most simple (for testing purposes) convert1
method is working as expected:
private convert1(response: Observable<TranslationRest>): Observable<Translation> {
return of({hello: 'hello transloco'})
}
html:
{{'hello' | transloco}}
displays in the browser: hello transloco
But how to implement real conversion? I tried to follow How to pipe / map an Observable in Angular but without luck:
private convert2(response: Observable<TranslationRest>): Observable<Translation> {
return response.pipe(
map((res: TranslationRest) => res.languageKeys.map(item =>{
item.key: item.value
}))
)
}
You're converting it incorrectly
private convert2(response: Observable<TranslationRest>): Observable<Translation> {
return response.pipe(
map((res: TranslationRest) => res.languageKeys.reduce((obj, item) => ({
...obj,
[item.key]: item.value,
}), {}))
)
}