I am looking for a robust way to prefetch a translation file from a server, and merge with the local translation file during app initialization.
The docs state that you can set the translation language using an APP_INITIALIZER
provider
https://ngneat.github.io/transloco/docs/recipes/prefetch
This may work if you only have a static json asset file (e.g. src/assets/i18n/en.json
), but I can't make this work combining with a json translation fetched from a server.
Here is my attempt at using the app initializer :
// app.module.ts
...
{
provide: APP_INITIALIZER,
multi: true,
useFactory: preloadServer,
deps: [TranslocoService, HttpClient]
}
...
export function preloadUser(transloco: TranslocoService, _httpClient: HttpClient) {
return () => {
combineLatest([
_httpClient.get(`http://my.server.com/en.json`), // fetches a remote translation
transloco.selectTranslation('en') // fetches the local static asset file
]).pipe(
take(1),
map(([server, client]) => (
Object.assign(client, server) // Merges the 2 objects
)),
tap(merged => transloco.setTranslation(merged, 'en')) // Updates the 'en' translation with the merged object
).toPromise();
}
}
Weird thing is that this randomly works. If I reload the app 10 times, half of the times I'll see the server translations and half the client translations.
Update
After @naren-murali 's answer, I realized that I can re-write the app initializer function to utilize the transloco API which provides a translation merge option, so I am adding my updated approach
export function preloadTranslation(transloco: TranslocoService, httpClient: HttpClient) {
return () => {
return concat(
transloco.selectTranslation('en'), // This fetches the local translation
httpClient.get(`http://my.server.com/en.json`) // This fetches the server translation
).pipe(
// Merge the server keys into the local object using the transloco API option "{ merge: true }"
tap(serverTranslation => transloco.setTranslation(serverTranslation, 'en', { merge: true }))
).toPromise();
}
}
Could you try returning the combineLatest
maybe that is what's missing!
export function preloadUser(transloco: TranslocoService, _httpClient: HttpClient) {
return () => {
return combineLatest([ // <-- changed here!
_httpClient.get(`http://my.server.com/en.json`), // fetches a remote translation
transloco.selectTranslation('en') // fetches the local static asset file
]).pipe(
take(1),
map(([server, client]) => (
Object.assign(client, server) // Merges the 2 objects
)),
tap(merged => transloco.setTranslation(merged, 'en')) // Updates the 'en' translation with the merged object
).toPromise();
}
}