Skip to content

Commit

Permalink
feat(TranslateService): add useDefaultLang config option for missing …
Browse files Browse the repository at this point in the history
…translations
  • Loading branch information
mmwlada authored and ocombe committed Jul 17, 2017
1 parent 1a15bc7 commit 942011c
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 4 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,8 @@ export class AppModule { }

You can setup a provider for the `MissingTranslationHandler` in the bootstrap of your application (recommended), or in the `providers` property of a component. It will be called when the requested translation is not available. The only required method is `handle` where you can do whatever you want. If this method returns a value or an observable (that should return a string), then this will be used. Just don't forget that it will be called synchronously from the `instant` method.

You can use `useDefaultLang` to decide whether default language string should be used when there is a missing translation in current language. Default value is true. If you set it to false, `MissingTranslationHandler` will be used instead of the default language string.

##### Example:

Create a Missing Translation Handler
Expand All @@ -375,7 +377,8 @@ Setup the Missing Translation Handler in your module import by adding it to the
imports: [
BrowserModule,
TranslateModule.forRoot({
missingTranslationHandler: {provide: MissingTranslationHandler, useClass: MyMissingTranslationHandler}
missingTranslationHandler: {provide: MissingTranslationHandler, useClass: MyMissingTranslationHandler},
useDefaultLang: false
})
],
providers: [
Expand Down
4 changes: 4 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {TranslateDirective} from "./src/translate.directive";
import {TranslatePipe} from "./src/translate.pipe";
import {TranslateStore} from "./src/translate.store";
import {USE_STORE} from "./src/translate.service";
import {USE_DEFAULT_LANG} from "./src/translate.service";

export * from "./src/translate.loader";
export * from "./src/translate.service";
Expand All @@ -21,6 +22,7 @@ export interface TranslateModuleConfig {
missingTranslationHandler?: Provider;
// isolate the service instance, only works for lazy loaded modules or components with the "providers" property
isolate?: boolean;
useDefaultLang?: boolean;
}

@NgModule({
Expand Down Expand Up @@ -48,6 +50,7 @@ export class TranslateModule {
config.missingTranslationHandler || {provide: MissingTranslationHandler, useClass: FakeMissingTranslationHandler},
TranslateStore,
{provide: USE_STORE, useValue: config.isolate},
{provide: USE_DEFAULT_LANG, useValue: config.useDefaultLang},
TranslateService
]
};
Expand All @@ -66,6 +69,7 @@ export class TranslateModule {
config.parser || {provide: TranslateParser, useClass: TranslateDefaultParser},
config.missingTranslationHandler || {provide: MissingTranslationHandler, useClass: FakeMissingTranslationHandler},
{provide: USE_STORE, useValue: config.isolate},
{provide: USE_DEFAULT_LANG, useValue: config.useDefaultLang},
TranslateService
]
};
Expand Down
5 changes: 4 additions & 1 deletion src/translate.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {TranslateParser} from "./translate.parser";
import {mergeDeep, isDefined} from "./util";

export const USE_STORE = new OpaqueToken('USE_STORE');
export const USE_DEFAULT_LANG = new OpaqueToken('USE_DEFAULT_LANG');

export interface TranslationChangeEvent {
translations: any;
Expand Down Expand Up @@ -154,11 +155,13 @@ export class TranslateService {
* @param parser An instance of the parser currently used
* @param missingTranslationHandler A handler for missing translations.
* @param isolate whether this service should use the store or not
* @param useDefaultLang whether we should use default language translation when current language translation is missing.
*/
constructor(public store: TranslateStore,
public currentLoader: TranslateLoader,
public parser: TranslateParser,
public missingTranslationHandler: MissingTranslationHandler,
@Inject(USE_DEFAULT_LANG) private useDefaultLang: boolean = true,
@Inject(USE_STORE) private isolate: boolean = false) {
}

Expand Down Expand Up @@ -348,7 +351,7 @@ export class TranslateService {
res = this.parser.interpolate(this.parser.getValue(translations, key), interpolateParams);
}

if(typeof res === "undefined" && this.defaultLang && this.defaultLang !== this.currentLang) {
if(typeof res === "undefined" && this.defaultLang && this.defaultLang !== this.currentLang && this.useDefaultLang) {
res = this.parser.interpolate(this.parser.getValue(this.translations[this.defaultLang], key), interpolateParams);
}

Expand Down
35 changes: 33 additions & 2 deletions tests/missing-translation-handler.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,14 @@ import {
} from "../index";

let translations: any = {"TEST": "This is a test"};
let fakeTranslation: any = {"NOT_USED": "not used"};

class FakeLoader implements TranslateLoader {
getTranslation(lang: string): Observable<any> {
if (lang === 'fake') {
return Observable.of(fakeTranslation);
}

return Observable.of(translations);
}
}
Expand All @@ -33,11 +39,12 @@ describe('MissingTranslationHandler', () => {
}
}

let prepare = ((handlerClass: Function) => {
let prepare = ((handlerClass: Function, defaultLang: boolean = true) => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot({
loader: {provide: TranslateLoader, useClass: FakeLoader}
loader: {provide: TranslateLoader, useClass: FakeLoader},
useDefaultLang: defaultLang
})
],
providers: [
Expand Down Expand Up @@ -182,4 +189,28 @@ describe('MissingTranslationHandler', () => {
nonExistingKey3: 'nonExistingKey3'
} as any);
});

it ('should not return default translation, but missing handler', () => {
prepare(Missing, false);
translate.use('en');
translate.use('fake');

spyOn(missingTranslationHandler, 'handle').and.callThrough();
translate.get('TEST').subscribe((res: string) => {
expect(missingTranslationHandler.handle).toHaveBeenCalledWith(jasmine.objectContaining({key: 'TEST'}));
//test that the instance of the last called argument is string
expect(res).toEqual('handled');
});
});

it ('should return default translation', () => {
prepare(Missing, true);
translate.use('en');
translate.use('fake');

spyOn(missingTranslationHandler, 'handle').and.callThrough();
translate.get('TEST').subscribe((res: string) => {
expect(res).toEqual('This is a test');
});
});
});

0 comments on commit 942011c

Please sign in to comment.