How to convert Observable<Some> to other Observable<Other>

409 Views Asked by At

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
      }))
    )
  }
1

There are 1 best solutions below

0
On BEST ANSWER

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,
      }), {}))
    )
}