diff --git a/projects/ngx-translate/core/src/lib/translate.service.ts b/projects/ngx-translate/core/src/lib/translate.service.ts index 61c0c532..85eb7dae 100644 --- a/projects/ngx-translate/core/src/lib/translate.service.ts +++ b/projects/ngx-translate/core/src/lib/translate.service.ts @@ -1,6 +1,6 @@ import {EventEmitter, Inject, Injectable, InjectionToken} from "@angular/core"; -import {concat, forkJoin, isObservable, Observable, of, defer} from "rxjs"; -import {concatMap, map, shareReplay, switchMap, take} from "rxjs/operators"; +import {concat, forkJoin, isObservable, Observable, of, defer, Subject} from "rxjs"; +import {concatMap, map, shareReplay, switchMap, take, takeUntil, tap} from "rxjs/operators"; import {MissingTranslationHandler, MissingTranslationHandlerParams} from "./missing-translation-handler"; import {TranslateCompiler} from "./translate.compiler"; import {TranslateLoader} from "./translate.loader"; @@ -42,6 +42,7 @@ export class TranslateService { private _onTranslationChange: EventEmitter = new EventEmitter(); private _onLangChange: EventEmitter = new EventEmitter(); private _onDefaultLangChange: EventEmitter = new EventEmitter(); + private _onRequestLangChange: Subject() = new Subject(); private _defaultLang: string; private _currentLang: string; private _langs: Array = []; @@ -201,6 +202,7 @@ export class TranslateService { * Changes the lang currently used */ public use(lang: string): Observable { + this._onRequestLangChange.next(); // don't change the language if the language given is already selected if (lang === this.currentLang) { return of(this.translations[lang]); @@ -214,11 +216,14 @@ export class TranslateService { this.currentLang = lang; } - pending.pipe(take(1)) - .subscribe((res: any) => { - this.changeLang(lang); - }); - + pending = pending.pipe( + takeUntil(this._onRequestLangChange), + take(1), + tap((res: any) => { + this.changeLang(lang); + }), + shareReplay()); + pending.subscribe(); return pending; } else { // we have this language, return an Observable this.changeLang(lang); diff --git a/projects/ngx-translate/core/tests/translate.service.spec.ts b/projects/ngx-translate/core/tests/translate.service.spec.ts index bc890d62..afd537be 100644 --- a/projects/ngx-translate/core/tests/translate.service.spec.ts +++ b/projects/ngx-translate/core/tests/translate.service.spec.ts @@ -1,11 +1,12 @@ import {fakeAsync, TestBed, tick} from "@angular/core/testing"; -import {Observable, of, timer, zip, defer} from "rxjs"; +import {Observable, of, Subject, timer, zip, defer} from "rxjs"; import {mapTo, take, toArray, first} from 'rxjs/operators'; import {LangChangeEvent, TranslateLoader, TranslateModule, TranslateService, TranslationChangeEvent} from '../src/public_api'; let translations: any = {"TEST": "This is a test"}; class FakeLoader implements TranslateLoader { + loaders: Map> = new Map(); getTranslation(lang: string): Observable { return of(translations); } @@ -13,6 +14,7 @@ class FakeLoader implements TranslateLoader { describe('TranslateService', () => { let translate: TranslateService; + let loader: FakeLoader; beforeEach(() => { TestBed.configureTestingModule({ @@ -23,6 +25,7 @@ describe('TranslateService', () => { ] }); translate = TestBed.get(TranslateService); + loader = TestBed.get(TranslateLoader); }); afterEach(() => { @@ -526,4 +529,21 @@ describe('TranslateService', () => { expect(translateCompilerCallCount).toBe(1); })); + + it('should load the last language requested even if another took longer to load', fakeAsync(() => { + translate.setTranslation('en', {"TEST": "This is a test"}); + translate.use('en'); + + const nlLoader: Subject = new Subject(); + loader.loaders.set('nl', nlLoader); + translate.use('nl'); + translate.use('en'); + + expect(translate.instant('TEST')).toEqual('This is a test'); + + nlLoader.next({"TEST": "Dit is een test"}); + nlLoader.compete(); + + expect(translate.instant('TEST')).toEqual('This is a test'); + })); });