0

I have an app with lazy loaded modules. I also have a shared module called MainModule. Here is my very simple service called LangService:

@Injectable({
    providedIn: 'root'
}) 

export class LangService {

    lang:string = "en";

    constructor(public translate: TranslateService) {
        this.translate.setDefaultLang( this.lang );
        this.translate.use( this.lang );
    }

    setLang( lang ) {
        this.translate.setDefaultLang( this.lang );
        this.translate.use( this.lang );
        this.lang = lang;
    }
}

In my tabs routing I have the following:

changeLang(lang) {
    // lang is for example "fr"
    this.langService.setLang(lang);
}

And my tabs html:

<Label [text]="'HOME.Title' | translate"></Label>

Now when I go to another route, in it's component I get the default value (not the changed value):

constructor(public langService:LangService) {
    // prints "en" !!!
    console.log(this.langService.lang);
};

I have provided the service in my shared module and import my shared module in everywhere:

providers: [
    LangService
],

I'm using Angular 7 with nativescript.

Vahid Najafi
  • 4,654
  • 11
  • 43
  • 88
  • 2
    You should be providing the service at root `@Injectable({ providedIn: 'root' })` and not as provider of SharedModule. This will allow you to have only on instance of it and will be available across the app, – nircraft May 07 '19 at 16:57
  • @nircraft I have it in my service. Updated. – Vahid Najafi May 07 '19 at 16:59
  • 1
    Also make sure to remove it from list of `providers` from any other module or `MainModule` – nircraft May 07 '19 at 17:01
  • @nircraft It's not possible. Because I use a translate service in my own service. When I remove `providers` it doesn't work. See updates please. – Vahid Najafi May 07 '19 at 17:16
  • You can have the LangService and Translate service both injected at root and not defined in Shared module. It would work fine when used at other route location. If you can share a [mcve], it would be great – nircraft May 07 '19 at 18:06

1 Answers1

1

In stead of providing the module in the MainModule which seems to create another instance each time a new module is loaded. You should be making your services Injectable at root.

Ex:

@Injectable({
    providedIn: 'root'
})
export class LangService {
}

The service now will have only one instance and can be used across and any updates will be visible to all modules. Also make sure to remove it from list of providers from any other module.

Any service injections to this service, should also be injected in root and not be part of providers of MainModule.

Check this example that i created here: The language set in app.component will display in the customer details screen which is lazy-loaded

Unless you are resetting the language anywhere else, it will show up as is.

nircraft
  • 8,242
  • 5
  • 30
  • 46
  • Thank you so much for attention. Let me describe more about this. LangService is my own service just to save user selected language. But TranslateService is a library's service (ngx-translate). If I add LangService to `providers` as you mentioned, it gives me a difference instantiate of lang property. But how about removing it from `providers` in SharedModule. First, let me tell that I inject TranslateService to handle translations. I do it because I don't want to repeat the logic in each component, Instead, use it in LangService based on user selection. – Vahid Najafi May 07 '19 at 20:17
  • But when I remove LangService from `providers` TranslateService doesn't work. – Vahid Najafi May 07 '19 at 20:18
  • @VahidNajafi, see if this helps you: https://stackoverflow.com/a/50243449/9386929 – nircraft May 07 '19 at 20:20
  • Thanks. Where should I use `super()` ? – Vahid Najafi May 07 '19 at 20:36
  • I asked my question in much more proper way here: https://stackoverflow.com/questions/56030377/angular-service-doesnt-work-within-other-service – Vahid Najafi May 07 '19 at 20:58