Skip to content

Commit

Permalink
fix(fallback): Allowing chomsky to work with just the base translatio…
Browse files Browse the repository at this point in the history
…n file
  • Loading branch information
Joshua Godi committed Mar 15, 2017
1 parent 9e9ed19 commit 8b6c7ba
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 32 deletions.
2 changes: 2 additions & 0 deletions demo/src/demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ chomsky.onLocaleChange.subscribe((locale: string) => {
const US_LOCALE = 'en-US';
const FR_LOCALE = 'fr-FR';
const GB_LOCALE = 'en-GB';
const MISSING_LOCALE = 'en-NOPE';

// Swap Locales
chomsky.use(US_LOCALE);
chomsky.use(FR_LOCALE);
chomsky.use(MISSING_LOCALE);
chomsky.use(GB_LOCALE).subscribe(() => {
// Load US again (should not fire XHR requests)
chomsky.use(US_LOCALE);
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "chomsky",
"version": "2.1.7",
"version": "2.1.8",
"description": "A simple ES6 i18n engine.",
"main": "lib/index.js",
"typings": "build/main/index.d.ts",
Expand Down Expand Up @@ -98,4 +98,4 @@
"dependencies": {
"tslib": "^1.5.0"
}
}
}
36 changes: 17 additions & 19 deletions src/lib/chomsky.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Subject } from 'rxjs/Subject';
import 'rxjs/add/observable/of';
import 'rxjs/add/observable/combineLatest';
import 'rxjs/add/operator/share';
import 'rxjs/add/observable/fromPromise';
// APP
import { Loader } from './loader';
import { Formats, IFormatDefaults } from './formats';
Expand Down Expand Up @@ -79,8 +80,6 @@ export class Chomsky {
private dictionaryManager = new DictionaryManager();
// Custom formats based on the locale
private formats = new Formats();
// Current pending call to fetch translations
private pending: any;
// Object for default replacements, so users don't have to pass around each time
private defaultReplacements: any = {};
// Handle for when the locale changes
Expand Down Expand Up @@ -230,22 +229,21 @@ export class Chomsky {
private getTranslations(locale: string): Observable<any> {
// Split out the language code from the locale
let languageCode = (locale.split('-')[0] || '').toLowerCase();
// Cue up two observables to grab the locale and the fallback locale
// en-US - locale (en-US) / fallback (en)
let translations = this.translationFetcher(locale);
let fallbackTranslations = this.translationFetcher(languageCode);
// Combine the two observables and share the same subscription
this.pending = Observable.combineLatest(translations, fallbackTranslations).share();
// Subscribe to the result
this.pending.subscribe(result => {
this.applyLanguage(locale, result[0], result[1]);
}, err => {
console.error('[Chomsky] - Fetching Translations Error:', err);
}, () => {
this.pending = undefined;
});

return this.pending;
// Fetch the fallback language first
return Observable.fromPromise(new Promise<any>((resolve, reject) => {
this.translationFetcher(languageCode).then(fallbackTranslations => {
this.translationFetcher(locale).then(translations => {
this.applyLanguage(locale, translations, fallbackTranslations);
resolve(true);
}, error => {
this.applyLanguage(locale, {}, fallbackTranslations);
resolve(true);
});
}, error => {
console.error(`[Chomsky] - Cannot find the base translation file! (${languageCode}):`, error);
resolve(false);
});
}));
}

private applyLanguage(locale: string, translations: any, fallbackTranslations: any): void {
Expand All @@ -270,7 +268,7 @@ export class Chomsky {
this.onLocaleChange.next(locale);
}

private translationFetcher(locale: string): Observable<string> {
private translationFetcher(locale: string): Promise<string> {
return this.loader.load(`${this.location}${locale}.json`);
}
}
5 changes: 4 additions & 1 deletion src/lib/dictionary-manager.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
// APP
import { mergeDeep } from './object-assign-deep';

export class DictionaryManager {
private dictionaries: any = {};

Expand All @@ -10,6 +13,6 @@ export class DictionaryManager {
}

public add(locale: string, translations: any, fallbackTranslations: any): void {
this.dictionaries[locale] = Object.assign({}, fallbackTranslations, translations);
this.dictionaries[locale] = mergeDeep({}, fallbackTranslations, translations);
}
}
6 changes: 3 additions & 3 deletions src/lib/loader.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,21 +27,21 @@ test('should have a method load', t => {

test('load should properly load a json file', t => {
let valid = { KEY: 'value' };
t.context.loader.load('/valid.json').subscribe(result => {
t.context.loader.load('/valid.json').then(result => {
t.deepEqual(result, valid);
});
server.requests[0].respond(200, { 'Content-Type': 'application/json' }, JSON.stringify(valid));
});

test('load should reject with JSON parse fails', t => {
t.context.loader.load('/invalid.json').subscribe(() => { }, error => {
t.context.loader.load('/invalid.json').then(() => { }, error => {
t.is(error, 'Parse Error: Invalid JSON');
});
server.requests[0].respond(200, { 'Content-Type': 'application/json' }, '["\t"]');
});

test('load should reject when 404 happens', t => {
t.context.loader.load('/404.json').subscribe(() => { }, error => {
t.context.loader.load('/404.json').then(() => { }, error => {
t.is(error, 'Not Found');
});
server.requests[0].respond(404);
Expand Down
10 changes: 3 additions & 7 deletions src/lib/loader.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
// Vendor
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromPromise';

/**
* @name Loader
* @description Loader to load the JSON translation files via HTTP
Expand All @@ -16,8 +12,8 @@ export class Loader {
* @returns {Observable<string>}
* @memberOf Loader
*/
public load(url: string): Observable<string> {
return Observable.fromPromise(new Promise((resolve, reject) => {
public load(url: string): Promise<string> {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open('GET', url);

Expand All @@ -38,6 +34,6 @@ export class Loader {
};

xhr.send();
}));
});
}
}

0 comments on commit 8b6c7ba

Please sign in to comment.