Custom Angular library with ngx-translate

I did it in a similar way as Beejee did, but I extended the translation service. In the extension of the TranslateService I add the library's translation under a sublevel (ui.[language]) of the global app's translations as we use the same instance as the root app does and we don't want to override translations of the root app. Then I provided the extension instead of the normal TranslateService at component level so it is used even for the translate directive within this component and it is isolated, meaning that we don't destroy root app's translation by overriding the getters for currentLang and defautlLang.

ui-translate.service.ts:


const availableLanguages: any = {
  'de' : { ... YOUR DE TRANSLATIONS ... },
  'en' : { ... YOUR EN TRANSLATIONS ... }
  ...
};
const langPrefix = 'ui';

@Injectable({
  providedIn: 'root'
})
export class UiTranslateService extends TranslateService implements TranslateService {


  constructor(public store: TranslateStore,
              public currentLoader: TranslateLoader,
              public compiler: TranslateCompiler,
              public parser: TranslateParser,
              public missingTranslationHandler: MissingTranslationHandler,
              @Inject(USE_DEFAULT_LANG) useDefaultLang: boolean = true,
              @Inject(USE_STORE) isolate: boolean = false) {
    super(store, currentLoader, compiler, parser, missingTranslationHandler, useDefaultLang, isolate);

    this.onTranslationChange.subscribe((_res: TranslationChangeEvent) => {
      // ensure after translation change we (re-)add our translations
      if (_res.lang.indexOf(langPrefix) !== 0) {
        this.applyUiTranslations();
      }
    });

    this.applyUiTranslations();
  }

  private applyUiTranslations() {
    for (var lang in availableLanguages) {
      if (availableLanguages.hasOwnProperty(lang)) {
        this.setTranslation(langPrefix + '.' + lang, availableLanguages[lang], true);
      }
    }
  }

  /**
   * The default lang to fallback when translations are missing on the current lang
   */
  get defaultLang(): string {
    return langPrefix + '.' + this.store.defaultLang;
  }

  /**
   * The lang currently used
   */
  get currentLang(): string {
    return this.store.currentLang === undefined ? undefined : langPrefix + '.' + this.store.currentLang;
  }

  public getParsedResult(translations: any, key: any, interpolateParams?: Object): any {
    // apply our translations here
    var lang = (this.currentLang || this.defaultLang).split('.')[1];
    translations = lang == 'de' ? de : en;
    return super.getParsedResult(translations, key, interpolateParams);
  }
  public get(key: string | Array<string>, interpolateParams?: Object): Observable<string | any> {
    return super.get(key, interpolateParams);
  }
}

my.component.ts:

    @Component({
        selector: 'xxx',
        template: 'xxx',
        providers: [
            { provide: TranslateService, useClass: UiTranslateService }
        ]
    })
    export class MyComponent implements OnInit { }

my.module.ts:

    @NgModule({
        imports: [
            CommonModule,
            TranslateModule
        ]
     })
     export class ComponentsModule {}

Because I was getting nowhere I tried out another approach as described in this post. So I converted my json files to ts files returning a json object. I then created my own translateService which adds the translations on top of the existing one's (those added by the json files of the main application) as described in the post.

This worked but overruled the previous translations or even loaded too late. This resulted in the application just showing the translationkeys instead of the translation. So instead of initializing the translations like in the post, I used a subscribe to wait on the main translations first.

//Library
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { en } from "../localization/en";
import { nl } from "../localization/nl";

@Injectable()
export class TranslateUiService {
    private availableLanguages = { en, nl };

    constructor(private translateService: TranslateService) {
    }

    public init(language: string = null): any {
        if (language) {
            //initialize one specific language
            this.translateService.setTranslation(language, this.availableLanguages[language], true);
        } else {
            //initialize all
            Object.keys(this.availableLanguages).forEach((language) => {
                this.translateService.setTranslation(language, this.availableLanguages[language], true);
            });
        }
    }
}

//App
constructor(private translateUiService: TranslateUiService, private translateService: TranslateService) {
        this.translateService.setDefaultLang('en');
        this.translateService.use('en').subscribe(() => {
            this.translateUiService.init('en');
        });
    }