11import { inject , Injectable , InjectionToken } from "@angular/core" ;
2- import { concat , defer , forkJoin , isObservable , Observable , of } from "rxjs" ;
2+ import { concat , defer , finalize , forkJoin , isObservable , Observable , of , tap } from "rxjs" ;
33import { concatMap , map , shareReplay , switchMap , take } from "rxjs/operators" ;
44import { MissingTranslationHandler } from "./missing-translation-handler" ;
55import { TranslateCompiler } from "./translate.compiler" ;
@@ -58,9 +58,7 @@ const makeObservable = <T>(value: T | Observable<T>): Observable<T> => {
5858
5959@Injectable ( )
6060export class TranslateService implements ITranslateService {
61- protected loadingTranslations ! : Observable < InterpolatableTranslationObject > ;
62- protected pending = false ;
63- protected _translationRequests : Record < Language , Observable < TranslationObject > > = { } ;
61+ protected loadingTranslations : Record < Language , Observable < InterpolatableTranslationObject > > = { } ;
6462 protected lastUseLanguage : Language | null = null ;
6563
6664 protected currentLoader = inject ( TranslateLoader ) ;
@@ -151,6 +149,11 @@ export class TranslateService implements ITranslateService {
151149 return of ( this . store . getTranslations ( lang ) ) ;
152150 }
153151
152+ protected isLoading ( ) : boolean
153+ {
154+ return Object . keys ( this . loadingTranslations ) . length > 0 ;
155+ }
156+
154157 /**
155158 * Changes the lang currently used
156159 */
@@ -185,12 +188,10 @@ export class TranslateService implements ITranslateService {
185188 /**
186189 * Retrieves the given translations
187190 */
188- protected loadOrExtendLanguage ( lang : Language ) : Observable < TranslationObject > | undefined {
191+ protected loadOrExtendLanguage ( lang : Language ) : Observable < InterpolatableTranslationObject > | undefined {
189192 // if this language is unavailable or extend is true, ask for it
190193 if ( ! this . store . hasTranslationFor ( lang ) || this . extend ) {
191- this . _translationRequests [ lang ] =
192- this . _translationRequests [ lang ] || this . loadAndCompileTranslations ( lang ) ;
193- return this . _translationRequests [ lang ] ;
194+ return this . loadAndCompileTranslations ( lang ) ;
194195 }
195196
196197 return undefined ;
@@ -216,30 +217,36 @@ export class TranslateService implements ITranslateService {
216217 protected loadAndCompileTranslations (
217218 lang : Language ,
218219 ) : Observable < InterpolatableTranslationObject > {
219- this . pending = true ;
220220
221- const loadingTranslations = this . currentLoader
222- . getTranslation ( lang )
223- . pipe ( shareReplay ( 1 ) , take ( 1 ) ) ;
221+ if ( this . loadingTranslations [ lang ] ) {
222+ return this . loadingTranslations [ lang ] ;
223+ }
224224
225- this . loadingTranslations = loadingTranslations . pipe (
226- map ( ( res : TranslationObject ) => this . compiler . compileTranslations ( res , lang ) ) ,
227- shareReplay ( 1 ) ,
228- take ( 1 ) ,
225+ const translations$ = this . currentLoader . getTranslation ( lang ) . pipe (
226+ map ( ( res : TranslationObject ) =>
227+ this . compiler . compileTranslations ( res , lang ) ,
228+ ) ,
229+ tap ( ( compiled : InterpolatableTranslationObject ) => {
230+ this . store . setTranslations ( lang , compiled , this . extend ) ;
231+ } ) ,
232+ finalize ( ( ) => {
233+ delete this . loadingTranslations [ lang ] ;
234+ } ) ,
235+ // cache the single result & share it across all subscribers
236+ shareReplay ( { bufferSize : 1 , refCount : true } ) ,
229237 ) ;
230238
231- this . loadingTranslations . subscribe ( {
232- next : ( res : InterpolatableTranslationObject ) => {
233- this . store . setTranslations ( lang , res , this . extend ) ;
234- this . pending = false ;
235- } ,
239+ this . loadingTranslations [ lang ] = translations$ ;
240+
241+ // trigger loading if nobody subscribes from outside
242+ translations$ . subscribe ( {
236243 error : ( err ) => {
237244 void err ;
238- this . pending = false ;
245+ // console.error(err) ;
239246 } ,
240247 } ) ;
241248
242- return loadingTranslations ;
249+ return translations$ ;
243250 }
244251
245252 /**
@@ -390,9 +397,10 @@ export class TranslateService implements ITranslateService {
390397 if ( ! isDefinedAndNotNull ( key ) || ! key . length ) {
391398 return of ( "" ) ;
392399 }
400+
393401 // check if we are loading a new translation to use
394- if ( this . pending ) {
395- return this . loadingTranslations . pipe (
402+ if ( this . lastUseLanguage && this . loadingTranslations [ this . lastUseLanguage ] ) {
403+ return this . loadingTranslations [ this . store . getCurrentLang ( ) ] . pipe (
396404 concatMap ( ( ) => {
397405 return makeObservable ( this . getParsedResult ( key , interpolateParams ) ) ;
398406 } ) ,
@@ -514,7 +522,7 @@ export class TranslateService implements ITranslateService {
514522 * Deletes inner translation
515523 */
516524 public resetLang ( lang : Language ) : void {
517- delete this . _translationRequests [ lang ] ;
525+ delete this . loadingTranslations [ lang ] ;
518526 this . store . deleteTranslations ( lang ) ;
519527 }
520528
0 commit comments