Skip to content

Commit 481365d

Browse files
DethArielocombe
authored andcommitted
feat(MissingTranslationHandler): pass additional paramaters to handle
Closes #160 Closes #214 Closes #221
1 parent 2156cac commit 481365d

File tree

3 files changed

+79
-16
lines changed

3 files changed

+79
-16
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,10 @@ Just don't forget that it will be called synchronously from the `instant` method
258258
##### Example:
259259
Create a Missing Translation Handler
260260
```ts
261-
import {MissingTranslationHandler} from 'ng2-translate';
261+
import {MissingTranslationHandler, MissingTranslationHandlerParams} from 'ng2-translate';
262262
263263
export class MyMissingTranslationHandler implements MissingTranslationHandler {
264-
handle(key: string) {
264+
handle(params: MissingTranslationHandlerParams) {
265265
return 'some value';
266266
}
267267
}

src/translate.service.ts

+33-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,29 @@ export interface LangChangeEvent {
2020
translations: any;
2121
}
2222

23+
export interface MissingTranslationHandlerParams {
24+
/**
25+
* the key that's missing in translation files
26+
*
27+
* @type {string}
28+
*/
29+
key: string;
30+
31+
/**
32+
* an instance of the service that was unable to translate the key.
33+
*
34+
* @type {TranslateService}
35+
*/
36+
translateService: TranslateService;
37+
38+
/**
39+
* interpolation params that were passed along for translating the given key.
40+
*
41+
* @type {Object}
42+
*/
43+
interpolateParams?: Object;
44+
}
45+
2346
declare interface Window {
2447
navigator: any;
2548
}
@@ -28,13 +51,15 @@ declare var window: Window;
2851
export abstract class MissingTranslationHandler {
2952
/**
3053
* A function that handles missing translations.
31-
* @param key the missing key
54+
*
55+
* @abstract
56+
* @param {MissingTranslationHandlerParams} the context for resolving a missing translation
3257
* @returns {any} a value or an observable
3358
* If it returns a value, then this value is used.
3459
* If it return an observable, the value returned by this observable will be used (except if the method was "instant").
3560
* If it doesn't return then the key will be used as a value
3661
*/
37-
abstract handle(key: string): any;
62+
abstract handle(params: MissingTranslationHandlerParams): any;
3863
}
3964

4065
export abstract class TranslateLoader {
@@ -252,8 +277,12 @@ export class TranslateService {
252277
res = this.parser.interpolate(this.parser.getValue(this.translations[this.defaultLang], key), interpolateParams);
253278
}
254279

255-
if(!res && this.missingTranslationHandler) {
256-
res = this.missingTranslationHandler.handle(key);
280+
if (!res && this.missingTranslationHandler) {
281+
let params: MissingTranslationHandlerParams = { key, translateService: this };
282+
if (typeof interpolateParams !== 'undefined') {
283+
params.interpolateParams = interpolateParams;
284+
}
285+
res = this.missingTranslationHandler.handle(params);
257286
}
258287

259288
return res !== undefined ? res : key;

tests/translate.service.spec.ts

+44-10
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {MockBackend, MockConnection} from "@angular/http/testing";
44
import {
55
TranslateService,
66
MissingTranslationHandler,
7+
MissingTranslationHandlerParams,
78
TranslateLoader,
89
TranslateStaticLoader,
910
LangChangeEvent,
@@ -310,23 +311,23 @@ describe('MissingTranslationHandler', () => {
310311
let missingTranslationHandler: MissingTranslationHandler;
311312

312313
class Missing implements MissingTranslationHandler {
313-
handle(key: string) {
314+
handle(params: MissingTranslationHandlerParams) {
314315
return "handled";
315316
}
316317
}
317318

318319
class MissingObs implements MissingTranslationHandler {
319-
handle(key: string): Observable<any> {
320-
return Observable.of(`handled: ${key}`);
320+
handle(params: MissingTranslationHandlerParams): Observable<any> {
321+
return Observable.of(`handled: ${params.key}`);
321322
}
322323
}
323324

324325
let prepare = ((handlerClass: Function) => {
325326
TestBed.configureTestingModule({
326327
imports: [HttpModule, TranslateModule.forRoot()],
327328
providers: [
328-
{provide: MissingTranslationHandler, useClass: handlerClass},
329-
{provide: XHRBackend, useClass: MockBackend}
329+
{ provide: MissingTranslationHandler, useClass: handlerClass },
330+
{ provide: XHRBackend, useClass: MockBackend }
330331
]
331332
});
332333
injector = getTestBed();
@@ -351,7 +352,40 @@ describe('MissingTranslationHandler', () => {
351352
spyOn(missingTranslationHandler, 'handle').and.callThrough();
352353

353354
translate.get('nonExistingKey').subscribe((res: string) => {
354-
expect(missingTranslationHandler.handle).toHaveBeenCalledWith('nonExistingKey');
355+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ key: 'nonExistingKey' }));
356+
//test that the instance of the last called argument is string
357+
expect(res).toEqual('handled');
358+
});
359+
360+
// mock response after the xhr request, otherwise it will be undefined
361+
mockBackendResponse(connection, '{"TEST": "This is a test"}');
362+
});
363+
364+
it('should propagate interpolation params when the key does not exist', () => {
365+
prepare(Missing);
366+
translate.use('en');
367+
spyOn(missingTranslationHandler, 'handle').and.callThrough();
368+
let interpolateParams = { some: 'params' };
369+
370+
translate.get('nonExistingKey', interpolateParams).subscribe((res: string) => {
371+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ interpolateParams: interpolateParams }));
372+
//test that the instance of the last called argument is string
373+
expect(res).toEqual('handled');
374+
});
375+
376+
// mock response after the xhr request, otherwise it will be undefined
377+
mockBackendResponse(connection, '{"TEST": "This is a test"}');
378+
});
379+
380+
it('should propagate TranslationService params when the key does not exist', () => {
381+
prepare(Missing);
382+
translate.use('en');
383+
spyOn(missingTranslationHandler, 'handle').and.callThrough();
384+
let interpolateParams = { some: 'params' };
385+
386+
translate.get('nonExistingKey', interpolateParams).subscribe((res: string) => {
387+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ translateService: translate }));
388+
//test that the instance of the last called argument is string
355389
expect(res).toEqual('handled');
356390
});
357391

@@ -361,7 +395,7 @@ describe('MissingTranslationHandler', () => {
361395

362396
it('should return the key when using MissingTranslationHandler & the handler returns nothing', () => {
363397
class MissingUndef implements MissingTranslationHandler {
364-
handle(key: string) {
398+
handle(params: MissingTranslationHandlerParams) {
365399
}
366400
}
367401

@@ -370,7 +404,7 @@ describe('MissingTranslationHandler', () => {
370404
spyOn(missingTranslationHandler, 'handle').and.callThrough();
371405

372406
translate.get('nonExistingKey').subscribe((res: string) => {
373-
expect(missingTranslationHandler.handle).toHaveBeenCalledWith('nonExistingKey');
407+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ key: 'nonExistingKey' }));
374408
expect(res).toEqual('nonExistingKey');
375409
});
376410

@@ -397,7 +431,7 @@ describe('MissingTranslationHandler', () => {
397431
spyOn(missingTranslationHandler, 'handle').and.callThrough();
398432

399433
expect(translate.instant('nonExistingKey')).toEqual('handled');
400-
expect(missingTranslationHandler.handle).toHaveBeenCalledWith('nonExistingKey');
434+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ key: 'nonExistingKey' }));
401435
});
402436

403437
it('should wait for the MissingTranslationHandler when it returns an observable & we use get', () => {
@@ -406,7 +440,7 @@ describe('MissingTranslationHandler', () => {
406440
spyOn(missingTranslationHandler, 'handle').and.callThrough();
407441

408442
translate.get('nonExistingKey').subscribe((res: string) => {
409-
expect(missingTranslationHandler.handle).toHaveBeenCalledWith('nonExistingKey');
443+
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({ key: 'nonExistingKey' }));
410444
expect(res).toEqual('handled: nonExistingKey');
411445
});
412446

0 commit comments

Comments
 (0)