0

I have the following scenario.

  • I have a custom translations library which serves to many angular applications.
    • Its a wrapper built around Transloco, which also has all my JSON files which have the translations
  • One of the consuming apps is a web application which works perfectly
  • The other one is an Ionic app, which works perfect when online, but when is offline it cant load the assets (even the library is already installed and the JSON files are inside the library)

I've read workarounds like this:Loading an local JSON file offline which suggest to change the JSON files to JS functions.

I would like to avoid this at all cost because its not scalable for me.

How can i preload the files when online conditionally (so it would only preload in the ionic app) and consume them when offline?

this is the custom translocoLoaderConfig which I made following their own documentation

@Injectable({ providedIn: 'root' })
export class TranslocoHttpLoaderService implements TranslocoLoader {
  constructor(
    @Inject(TRANSLOCO_LOADER_CONFIG)
    private translocoLoaderConfig: TranslocoLoaderConfig
  ) {}

  getTranslation(lang: string): Observable<Translation> {
    const global: Promise<Translation> = this.getLanguage(lang).then((x) => {
      return x.default;
    });

    // to load in case API has customLiterals for this account
    if (this.translocoLoaderConfig.disableCustomLiterals) {
      return from(global);
    }
  
    const ObservableWithApiLogic = API_LOGIC_CALL.pipe(
        map((el: any) => {
          if (!el.value) return {};

          let customLiterals = JSON.parse(el.value);
         // Flatten the translations object
          customLiterals = customLiterals.reduce(
            (acc: Translation, curr: any) => ({ ...acc, ...curr }),
            {} as Translation
          );
          return customLiterals;
        })
      );
    return ObservableWithApiLogic.pipe(
      startWith(null),
      combineLatestWith(global),
      map(([accountTranslations, global]) => {
        return {
          ...global,
          ...(accountTranslations ? accountTranslations : {}),
        };
      }),
      // transform the @: syntax that makes reference to other labels with the {{}} transloco syntax
      map((translations) => {
        return transformValuesRecursively(translations, (value) => {
          if (value.startsWith('@:')) {
            return '{{' + value.slice(2) + '}}';
          }
          return value;
        });
      })
    );
  }

  // * method to import dynamically the language JSON file,
  // ! do not refactor to dynamic imports, otherwise the built
  // ! translation library will ignore the rest of the JSON files
  // ! and wont add them to the translation package when updated the published version
  getLanguage(lang: string) {
    switch (lang) {
      case 'es':
        return import('./i18n/es');
      case 'fr':
        return import('./i18n/fr/fr.json');
      default:
        // 'en'
        return import('./i18n/en/en.json');
    }
  }
}
// utility function that recursively transform the string values of an object.
const transformValuesRecursively = (
  object: any,
  tfunction: (value: string) => string
) => {
  const newObject = {} as any;
  Object.entries(object).forEach(([key, value]) => {
    if (typeof value === 'string') {
      newObject[key] = tfunction(value);
    } else {
      newObject[key] = transformValuesRecursively(value, tfunction);
    }
  });
  return newObject;
};
Pato
  • 189
  • 1
  • 9

0 Answers0