最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Update translations in loader of ngx-translate - Stack Overflow

programmeradmin2浏览0评论

I am creating a custom Angular ngx-translate Loader which either gets translations from cache or from an API. The point where I am stuck is Case 2 (see code below):

Desired procedure:

  1. gets translations from cache (sync)
  2. returns cached translations (via observer)
  3. gets translations from api (async)
  4. pares cache and api (finds difference)
  5. sends updated version of translations <-- How?

This is what I got:

getTranslation(lang: string): Observable<any> {
    return new Observable(observer => {

      // get translations from cache + start getting translations from API
      const cachedTranslations = this.cacheService.getTranslation(lang);
      const apiTranslations = this.http.get(environment.translationApi + lang);


      if (cachedTranslations) {
        // CASE #1: return cached translations
        observer.next(cachedTranslations);
      }

      apiTranslations.subscribe(translations => {
        // CASE #2: if cached translations are not up to date
        // or dont exist, add new translations and reload lang
        if (JSON.stringify(translations) !== JSON.stringify(cachedTranslations)) {
          this.cacheService.setTranslations(lang, translations);
          observer.next(translations);
        }

        observerplete();
      }, () => {
        observerplete();
      });

    });
}

Using observer.next() works only once, even if it isn't pleted yet. So how do I update the translations in Case 2 where an observer.next() already happend in Case 1?

I am creating a custom Angular ngx-translate Loader which either gets translations from cache or from an API. The point where I am stuck is Case 2 (see code below):

Desired procedure:

  1. gets translations from cache (sync)
  2. returns cached translations (via observer)
  3. gets translations from api (async)
  4. pares cache and api (finds difference)
  5. sends updated version of translations <-- How?

This is what I got:

getTranslation(lang: string): Observable<any> {
    return new Observable(observer => {

      // get translations from cache + start getting translations from API
      const cachedTranslations = this.cacheService.getTranslation(lang);
      const apiTranslations = this.http.get(environment.translationApi + lang);


      if (cachedTranslations) {
        // CASE #1: return cached translations
        observer.next(cachedTranslations);
      }

      apiTranslations.subscribe(translations => {
        // CASE #2: if cached translations are not up to date
        // or dont exist, add new translations and reload lang
        if (JSON.stringify(translations) !== JSON.stringify(cachedTranslations)) {
          this.cacheService.setTranslations(lang, translations);
          observer.next(translations);
        }

        observer.plete();
      }, () => {
        observer.plete();
      });

    });
}

Using observer.next() works only once, even if it isn't pleted yet. So how do I update the translations in Case 2 where an observer.next() already happend in Case 1?

Share Improve this question asked Nov 30, 2018 at 12:53 ZammyZammy 5733 silver badges22 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 6

This answer might not be relevant to you anymore, since it's been a few months, but I'll just leave it here, in case anybody stumbles over this question in the future, just like I did, when I was looking for a solution to this problem:

So it seems like pushing two different values into the observable in the getTranslation function messes with ngx-translate - I found a work around though.

I'm not sure if this is the best way to do it, but it works and solves my problem, so I'm just gonna go ahead and use it.

CustomTranslateLoader:

getTranslation(lang: string): Observable<any> {
    const translations = new BehaviorSubject(undefined);          
    translations.next(JSON.parse(this.localStorageService.getItem('translations')));
    return translations;
}

loadTranslation(lang) {
    return this.blockpitApiService.get('/translations/' + lang);
}

app.ponent.ts

constructor(
    private translate: TranslateService,
    private translateService: CustomTranslateLoader,
    private localStorageService: LocalStorageService
) {

    language = translate.getBrowserLang();
    translate.setDefaultLang(language);

    // load translations from server and update translations
    this.translateService.loadTranslation(language).subscribe(response => {
        this.localStorageService.setItem('translations', JSON.stringify(response.data));
        translate.setTranslation(language, response.data);
        translate.use(language);
    });
 }

Since ngx-translate simply ignores when we push new translations into the observable, we can simply call translate.setTranslation(language, response.data) and translate.use(language), to update the values used when translating.
By calling this as soon as our api call is finished, we initially see the translation that are first set in getTranslation which ngx-translation calls automatically and the api translations as soon as they are available when we .subscribe to the function in our app.ponent.ts.

This might not be ideal but it works and seems like an ok workaround - at least to me.

发布评论

评论列表(0)

  1. 暂无评论