File

angular/projects/researchdatabox/portal-ng-common/src/lib/translation.service.ts

Description

Translation related functions. Uses i18next library to support translation source for both frontend and backend.

Author: Shilo Banihit

Index

Properties
Methods

Constructor

constructor(rootContext: string, i18NextService: ITranslationService, utilService: UtilityService, configService: ConfigService, loggerService: LoggerService)
Parameters :
Name Type Optional
rootContext string No
i18NextService ITranslationService No
utilService UtilityService No
configService ConfigService No
loggerService LoggerService No

Methods

Public getConfig
getConfig(appName?: string)
Parameters :
Name Type Optional
appName string Yes
Returns : any
Public getInitSubject
getInitSubject()
Returns : Subject<any>
Async initTranslator
initTranslator()
Returns : Promise<any>
Public isInitializing
isInitializing()
Returns : boolean
t
t(key: string)
Parameters :
Name Type Optional
key string No
Returns : any
translatorLoaded
translatorLoaded()
Returns : void
Async waitForInit
waitForInit()
Returns : Promise<any>

Properties

Protected config
Type : any
Protected i18NextOpts
Type : any
Protected i18NextOptsDefault
Type : object
Default value : { load: 'languageOnly', supportedLngs: ['en'], fallbackLng: 'en', debug: true, returnEmptyString: false, ns: [ 'translation' ], interpolation: { format: I18NextModule.interpolationFormat(defaultInterpolationFormat) }, // lang detection plugin options detection: { // order and from where user language should be detected order: ['cookie'], // keys or params to lookup language from lookupCookie: 'lng', // cache user language on caches: ['cookie'], // optional expire and domain for set cookie cookieMinutes: 10080, // 7 days // cookieDomain: I18NEXT_LANG_COOKIE_DOMAIN } }
Public loadPath
Type : string
Default value : ''
Public rootContext
Type : string
Decorators :
@Inject(APP_BASE_HREF)
Protected subjects
Type : any
Protected translatorReady
Type : boolean
Default value : false
Public ts
Type : any
import { Injectable, Inject } from '@angular/core';
import { Subject, firstValueFrom } from 'rxjs';
import { APP_BASE_HREF } from '@angular/common';
import { get as _get, isEmpty as _isEmpty, isUndefined as _isUndefined, set as _set } from 'lodash-es';

import { Service } from './service.interface';

import { I18NEXT_SERVICE, ITranslationService, defaultInterpolationFormat, I18NextModule } from 'angular-i18next';
import HttpApi from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';
import { ConfigService } from './config.service';
import { UtilityService } from './utility.service';
import { LoggerService  } from './logger.service';
/**
 * Translation related functions. Uses i18next library to support translation source for both frontend and backend.
 *
 * Author: <a href='https://github.com/shilob' target='_blank'>Shilo Banihit</a>
 *
 * 
 */
@Injectable()
export class TranslationService implements Service {
  protected config: any;
  protected subjects: any;
  protected translatorReady: boolean = false;
  public loadPath: string = '';
  public ts: any;
  protected i18NextOpts: any;
  protected i18NextOptsDefault = {
    load: 'languageOnly',
    supportedLngs: ['en'],
    fallbackLng: 'en',
    debug: true,
    returnEmptyString: false,
    ns: [
      'translation'
    ],
    interpolation: {
      format: I18NextModule.interpolationFormat(defaultInterpolationFormat)
    },
    // lang detection plugin options
    detection: {
      // order and from where user language should be detected
      order: ['cookie'],
      // keys or params to lookup language from
      lookupCookie: 'lng',
      // cache user language on
      caches: ['cookie'],
      // optional expire and domain for set cookie
      cookieMinutes: 10080, // 7 days
      // cookieDomain: I18NEXT_LANG_COOKIE_DOMAIN
    }
  };
  
  constructor (
    @Inject(APP_BASE_HREF) public rootContext: string, 
    @Inject(I18NEXT_SERVICE) private i18NextService: ITranslationService,
    @Inject(UtilityService) private utilService: UtilityService,
    @Inject(ConfigService) private configService: ConfigService,
    @Inject(LoggerService) private loggerService: LoggerService
    ) {
    this.subjects = {};
    this.subjects['init'] = new Subject<any>();
    this.ts = new Date().getTime();
    // default loadPath
    this.loadPath = `${this.rootContext}/locales/{{lng}}/{{ns}}.json`;
  }

  async initTranslator(): Promise<any> {
    await this.utilService.waitForDependencies([this.configService]);
    this.config = await this.configService.getConfig();
    if (!_isEmpty(_get(this.config, 'i18NextOpts'))) {
      this.i18NextOpts = _get(this.config, 'i18NextOpts');
      if (_isUndefined(_get(this.i18NextOpts, 'backend.loadPath'))) {
        _set(this.i18NextOpts, 'backend.loadPath', this.loadPath);
      }
      if (_isUndefined(_get(this.i18NextOpts, 'interpolation'))) {
        _set(this.i18NextOpts, 'interpolation', this.i18NextOptsDefault.interpolation);
      }
    } else {
      // default value...
      this.loggerService.info(`Language service using default config`);
      this.i18NextOpts = this.i18NextOptsDefault;
      _set(this.i18NextOpts, 'backend.loadPath', this.loadPath);
    }
    this.loggerService.log(`Using language loadpath: ${this.loadPath}`);
    try {
    	await this.i18NextService
	              .use(HttpApi)
                .use(LanguageDetector)
	              .init(this.i18NextOpts);
      this.loggerService.info(`Language service ready`);
	    this.translatorReady = true;
	    this.translatorLoaded();
    } catch (error) {
      this.loggerService.error(`Failed to initialise language service:`) ;
      this.loggerService.error(JSON.stringify(error));
      throw error;
    }
    return this;
  }

  translatorLoaded() {
    if (this.translatorReady) {
      this.subjects['init'].next(this);
    }
  }

  t(key: string) {
    return this.i18NextService.t(key);
  }

  public getInitSubject(): Subject<any> {
    return this.subjects['init'];
  } 

  async waitForInit(): Promise<any> {
    if (this.translatorReady) {
      return this;
    } 
    if (_isUndefined(this.i18NextOpts)) {
      this.initTranslator();
    }
    return firstValueFrom(this.getInitSubject());
  }

  public isInitializing(): boolean {
    return !this.translatorReady;
  }

  public getConfig(appName?:string) {
    return this.config;
  }
}

results matching ""

    No results matching ""