diff --git a/README.md b/README.md index 6cd72317..4819a258 100644 --- a/README.md +++ b/README.md @@ -140,7 +140,9 @@ translate.setTranslation('en', { - `getLangs()`: Returns an array of currently available langs - `get(key: string|Array, interpolateParams?: Object): Observable`: Gets the translated value of a key (or an array of keys) - `instant(key: string|Array, interpolateParams?: Object): string|Object`: Gets the instant translated value of a key (or an array of keys) -- `set(key: string, value: string, lang?: string)`: set the translated value of a key +- `set(key: string, value: string, lang?: string)`: Sets the translated value of a key +- `reloadLang(lang: string): Observable`: Calls resetLang and retrieves the translations object for the current loader +- `resetLang(lang: string)`: Removes the current translations for this lang. /!\ You will have to call `use`, `reloadLang` or `getTranslation` again to be able to get translations #### Write & use your own loader If you want to write your own loader, you need to create a class that implements `TranslateLoader`. diff --git a/bundles/ng2-translate.js b/bundles/ng2-translate.js index c69453c1..9429ed71 100644 --- a/bundles/ng2-translate.js +++ b/bundles/ng2-translate.js @@ -353,6 +353,13 @@ System.registerDynamic("src/translate.service", ["angular2/core", "angular2/http translations: this.translations[lang] }); }; + TranslateService.prototype.reloadLang = function(lang) { + this.resetLang(lang); + return this.getTranslation(lang); + }; + TranslateService.prototype.resetLang = function(lang) { + this.translations[lang] = undefined; + }; TranslateService = __decorate([core_1.Injectable(), __param(2, core_1.Optional()), __metadata('design:paramtypes', [http_1.Http, TranslateLoader, MissingTranslationHandler])], TranslateService); return TranslateService; }()); diff --git a/src/translate.service.ts b/src/translate.service.ts index 792295d3..f5952dd8 100644 --- a/src/translate.service.ts +++ b/src/translate.service.ts @@ -291,4 +291,21 @@ export class TranslateService { this.onLangChange.emit({lang: lang, translations: this.translations[lang]}); } + /** + * Allows to reload the lang file from the file + * @param lang + * @returns {Observable} + */ + public reloadLang(lang: string): Observable { + this.resetLang(lang); + return this.getTranslation(lang); + } + + /** + * Deletes inner translation + * @param lang + */ + public resetLang(lang: string): void { + this.translations[lang] = undefined; + } } diff --git a/tests/translate.service.spec.ts b/tests/translate.service.spec.ts index 7c8a1275..ae79eadf 100644 --- a/tests/translate.service.spec.ts +++ b/tests/translate.service.spec.ts @@ -19,7 +19,6 @@ export function main() { connection.mockRespond(new Response(new ResponseOptions({body: response}))); }; - describe('TranslateService', () => { let injector: Injector; let backend: MockBackend; @@ -195,15 +194,62 @@ export function main() { }); translate.use('en'); }); + + it('should be able to reset a lang', (done: Function) => { + translate.use('en'); + spyOn(connection, 'mockRespond').and.callThrough(); + + // this will request the translation from the backend because we use a static files loader for TranslateService + translate.get('TEST').subscribe((res: string) => { + expect(res).toEqual('This is a test'); + expect(connection.mockRespond).toHaveBeenCalledTimes(1); + + // reset the lang as if it was never initiated + translate.resetLang('en'); + + expect(translate.instant('TEST')).toEqual('TEST'); + + // use set timeout because no request is really made and we need to trigger zone to resolve the observable + setTimeout(() => { + translate.get('TEST').subscribe((res: string) => { + expect(res).toEqual('TEST'); // because the loader is "pristine" as if it was never called + expect(connection.mockRespond).toHaveBeenCalledTimes(1); + done(); + }); + }, 10); + }); + + // mock response after the xhr request, otherwise it will be undefined + mockBackendResponse(connection, '{"TEST": "This is a test"}'); + }); + + it('should be able to reload a lang', () => { + translate.use('en'); + + // this will request the translation from the backend because we use a static files loader for TranslateService + translate.get('TEST').subscribe((res: string) => { + expect(res).toEqual('This is a test'); + + // reset the lang as if it was never initiated + translate.reloadLang('en').subscribe((res: string) => { + expect(translate.instant('TEST')).toEqual('This is a test 2'); + }); + + mockBackendResponse(connection, '{"TEST": "This is a test 2"}'); + }); + + // mock response after the xhr request, otherwise it will be undefined + mockBackendResponse(connection, '{"TEST": "This is a test"}'); + }); }); - + describe('MissingTranslationHandler', () => { let injector: Injector; let backend: MockBackend; let translate: TranslateService; let connection: MockConnection; // this will be set when a new connection is emitted from the backend. let missingTranslationHandler: MissingTranslationHandler; - + class Missing implements MissingTranslationHandler { handle(key: string) { return "handled"; @@ -243,7 +289,7 @@ export function main() { prepare(Missing); translate.use('en'); spyOn(missingTranslationHandler, 'handle').and.callThrough(); - + translate.get('nonExistingKey').subscribe((res: string) => { expect(missingTranslationHandler.handle).toHaveBeenCalledWith('nonExistingKey'); expect(res).toEqual('handled'); @@ -270,16 +316,16 @@ export function main() { // mock response after the xhr request, otherwise it will be undefined mockBackendResponse(connection, '{"TEST": "This is a test"}'); }); - + it('should not call the MissingTranslationHandler when the key exists', () => { prepare(Missing); translate.use('en'); spyOn(missingTranslationHandler, 'handle').and.callThrough(); - + translate.get('TEST').subscribe(() => { expect(missingTranslationHandler.handle).not.toHaveBeenCalled(); }); - + // mock response after the xhr request, otherwise it will be undefined mockBackendResponse(connection, '{"TEST": "This is a test"}'); });