Skip to content

Commit

Permalink
feat(TranslateService): Use the default language as a fallback
Browse files Browse the repository at this point in the history
Fixes #16
  • Loading branch information
ocombe committed Jan 17, 2016
1 parent d50649f commit 98f90c8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 9 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class AppComponent {
var userLang = navigator.language.split('-')[0]; // use navigator lang if available
userLang = /(fr|en)/gi.test(userLang) ? userLang : 'en';

// optional, default is "en"
// this language will be used as a fallback when a translation isn't found in the current language
translate.setDefaultLang('en');

// the lang to use, if the lang isn't available, it will use the current loader to get them
Expand Down Expand Up @@ -100,7 +100,7 @@ translate.setTranslation('en', {

#### Methods:
- `useStaticFilesLoader()`: Use a static files loader
- `setDefaultLang(lang: string)`: Sets the default language to use ('en' by default)
- `setDefaultLang(lang: string)`: Sets the default language to use as a fallback
- `use(lang: string): Observable<any>`: Changes the lang currently used
- `getTranslation(lang: string): Observable<any>`: Gets an object of translations for a given language with the current loader
- `setTranslation(lang: string, translations: Object)`: Manually sets an object of translations for a given language
Expand Down
19 changes: 14 additions & 5 deletions src/translate.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class TranslateService {

private pending: any;
private translations: any = {};
private defaultLang: string = 'en';
private defaultLang: string;
private langs: Array<string>;
private parser: Parser = new Parser();

Expand All @@ -81,7 +81,7 @@ export class TranslateService {
}

/**
* Sets the default language to use ('en' by default)
* Sets the default language to use as a fallback
* @param lang
*/
public setDefaultLang(lang: string) {
Expand Down Expand Up @@ -163,6 +163,7 @@ export class TranslateService {
if(!key) {
throw new Error('Parameter "key" required');
}

var getParsedResult = (translations: any, key: any) => {
if(!translations) {
return key;
Expand All @@ -174,15 +175,23 @@ export class TranslateService {
}
return result;
}
return this.parser.interpolate(translations[key], interpolateParams) || key
var res: string = this.parser.interpolate(translations[key], interpolateParams);

if(typeof res === 'undefined' && this.defaultLang && this.defaultLang !== this.currentLang) {
let translations: any = this.parser.flattenObject(this.translations[this.defaultLang]);
res = this.parser.interpolate(translations[key], interpolateParams);
}

return res || key;
};

// check if we are loading a new translation to use
if(this.pending) {
return this.pending.map((res: any) => {
return getParsedResult(this.parser.flattenObject(res), key);
});
} else {
let translations = this.parser.flattenObject(this.translations[this.currentLang]);
let translations: any = this.parser.flattenObject(this.translations[this.currentLang]);
return Observable.of(getParsedResult(translations, key));
}
}
Expand All @@ -200,7 +209,7 @@ export class TranslateService {

private changeLang(lang: string) {
this.currentLang = lang;
this.onLangChange.next({lang: lang, translations: this.translations[lang]});
this.onLangChange.emit({lang: lang, translations: this.translations[lang]});
}

}
35 changes: 33 additions & 2 deletions tests/translate.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ export function main() {
let translate: TranslateService;
var connection: MockConnection; // this will be set when a new connection is emitted from the backend.

var prepareStaticTranslate = () => {
var prepareStaticTranslate = (lang: string = 'en') => {
// this will load translate json files from src/public/i18n
translate.useStaticFilesLoader();

// the lang to use, if the lang isn't available, it will use the current loader to get them
translate.use('en');
translate.use(lang);
};

var mockBackendResponse = (response: string) => {
Expand All @@ -40,6 +40,13 @@ export function main() {
backend.connections.subscribe((c: MockConnection) => connection = c);
});

afterEach(() => {
injector = undefined;
backend = undefined;
translate = undefined;
connection = undefined;
});

it('is defined', () => {
expect(TranslateService).toBeDefined();
expect(translate).toBeDefined();
Expand All @@ -63,6 +70,19 @@ export function main() {
});
});

it("should fallback to the default language", () => {
prepareStaticTranslate("fr");

translate.setDefaultLang('en');
translate.setTranslation('en', {"TEST": "This is a test"});

translate.get('TEST').subscribe((res: string) => {
expect(res).toEqual('This is a test');
});

mockBackendResponse('{}');
});

it("should return the key when it doesn't find a translation", () => {
prepareStaticTranslate();

Expand Down Expand Up @@ -114,5 +134,16 @@ export function main() {
expect(res).toEqual('This is another test');
});
});

it("shouldn't do a request to the backend if you set the translation yourself", (done: Function) => {
translate.setTranslation('en', {"TEST": "This is a test"});
prepareStaticTranslate();

translate.get('TEST').subscribe((res: string) => {
expect(res).toEqual('This is a test');
expect(connection).not.toBeDefined();
done();
});
});
});
}

1 comment on commit 98f90c8

@darxx
Copy link

@darxx darxx commented on 98f90c8 Jun 16, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http://prntscr.com/bgp58h How to unit test this case? if navigator.language is read only?

Please sign in to comment.