Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sometimes DefaultLang translations are not loaded when starting the app #1347

Closed
ewolfman opened this issue Nov 11, 2021 · 5 comments
Closed

Comments

@ewolfman
Copy link

Current behavior

This issue may be similar to: #1162.

In my case I noticed that the app, while in production, sometimes fails to fallback to the default language on the first loaded screen (i.e. app first startup on load).

For example:

  1. Main resources file is 'en.json'. There is also an additional 'es.json' which is empty '{}'.
  2. When the app loads it sets 'en' as the default language: this.translate.setDefaultLang('en');
  3. The app upon startup sets the current lang to 'es': this.translate.use('es').
  4. In this case, sometimes, the fallback to 'en' fails and I see the resource key instead.

Some observations:

  1. If the app sets the language to be 'en' on startup, I don't see the problem reoccur.
  2. If the es.json file is not empty but has a translation, the problem does not occur.

For these reasons I suspect that the problem is with falling back to the default language when a resource is missing.

I tried various solutions to delay loading and ensure the translations are available but unfortunately could not workaround these problems. Here are some of the things I tried:

Expected behavior

The default language should be used for missing keys in the selected language, also upon application startup.

Environment


ngx-translate version: 13.0.0
Angular version: 12.1.0

Browser:
- Chrome (desktop) version 95
 
For Tooling issues:
- Node version: 14.17.1
- Platform:  win32 x64
@rbalet
Copy link

rbalet commented Nov 18, 2021

Hi @ewolfman. I had the same problem, which came funnily from my httpInterceptor.

I was using the angular http to load my file, but it was then delayed by my httpInterceptor, which then had created a problem while instantiating the TranslateService.

Here's how I fixed it.

1. I recreated the MultiTranslateHttpLoader to be able to add the X-Skip-Interceptor

export class MegaphoneMultiTranslateHttpLoader implements TranslateLoader {
  constructor(private http: HttpClient, private resourcesPrefix: string[]) {}

  public getTranslation(lang: string): Observable<any> {
  
  
    const headers = new HttpHeaders() // <-- Skipping httpInerceptor
      .set('X-Skip-Interceptor', '')
      .set('Content-Type', 'application/json; charset=utf-8')

    const requests = this.resourcesPrefix.map((prefix) => {
      const path = `${prefix}${lang}.json`

      return this.http.get(path, { headers }).pipe(
        catchError((res) => {
          console.group('MegaphoneMultiTranslateHttpLoader')
          console.error('Something went wrong for the following translation file:', path)
          console.error('Content of the error: ', res)
          console.groupEnd()
          return of({})
        }),
      )
    })

    return forkJoin(requests).pipe(map((response) => merge.all(response)))
  }
}

2. Skip it in the httpInterceptor

Here, I listen to the headers, if it does have the InterceptorSkipHeader, skip it

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
  const InterceptorSkipHeader = 'X-Skip-Interceptor'

    if (request.headers.has(InterceptorSkipHeader)) {
      const headers = request.headers.delete(InterceptorSkipHeader)
      return next.handle(request.clone({ headers }))
    }
  // ...
}

@ocombe I think this could be communicated somewhere in the wiki

@krutkowski86
Copy link

@rbalet just try to use HttpBackend instead of HttpClient inside your custom translate loader. It will skip your interceptors.

@rbalet
Copy link

rbalet commented Oct 21, 2022

@krutkowski86 Thx! I didn't though of it, here's the new code

import { HttpBackend, HttpClient } from '@angular/common/http'
import { TranslateLoader } from '@ngx-translate/core'
import * as merge from 'deepmerge'
import { forkJoin, Observable, of } from 'rxjs'
import { catchError, map } from 'rxjs/operators'

export class MegaMultiTranslateHttpLoader implements TranslateLoader {
  constructor(private _handler: HttpBackend, private _resourcesPrefix: string[]) {}

  public getTranslation(lang: string): Observable<any> {
    const requests = this._resourcesPrefix.map((prefix) => {
      const path = `${prefix}${lang}.json`

      return new HttpClient(this._handler).get(path).pipe(
        catchError((res) => {
          console.group('MegaMultiTranslateHttpLoader')
          console.error('Something went wrong for the following translation file:', path)
          console.error('Content of the error: ', res)
          console.groupEnd()
          return of({})
        }),
      )
    })

    return forkJoin(requests).pipe(map((response) => merge.all(response)))
  }
}

@rbalet
Copy link

rbalet commented Oct 22, 2022

@ewolfman Should be fixed on the latest version of this library https://www.npmjs.com/package/ngx-translate-multi-http-loader.

Can you try this out ?

@rbalet
Copy link

rbalet commented Oct 31, 2022

@ocombe Feel free to close this issue since I took over the library that was causing the problem & fixed the problem there

@ocombe ocombe closed this as completed Oct 31, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants