1

I'm trying to inject an @Injectable AppState as a singleton:

@Injectable()
export class AppState {
  public user: string;

  constructor() {

  }
...

I've set it on AppModule as provider:

// Application wide providers
const APP_PROVIDERS = [
  AppState
];

@NgModule({
  bootstrap: [ App ],
  declarations: [
    App,
    ErrorComponent
  ],
  imports: [ // import Angular's modules
    BrowserModule,
    FormsModule,
    HttpModule,
    RouterModule.forRoot(ROUTES, { useHash: true })
  ],
  providers: [
    APP_PROVIDERS
  ]
})

So, I've just created a "submodule":

@NgModule({
  //...
  providers: [ UsersService, AppState ]
})
export default class LoginModule {

On LoginComponent I do:

export class Login implements OnInit {

    constructor(private appState: AppState) {}

    public doLogin():void {
        this.appState.user = this.form.value.mail;
    }
}

Nevertheless, on another component named Profile, it seems that this.appState.user is undefined.

@NgModule({
  //...
  providers: [ AppState ]
})
export default class ProfileModule { /... }

@Component({
  //...
})
export class Profile implements OnInit {

  constructor(private appState: AppState) {

  }

  ngOnInit():void {
    this.user = this.appState.user;  <<<<<<<<<<<<< it's undefined
  }
}

Why this.appState.user is undifined if I'set it before in another component?

Jordi
  • 20,868
  • 39
  • 149
  • 333
  • 2
    You read it probably before it is set. Services (injectables) are singleton by default when you provide it only in non-lazy loaded modules. Only when you add it to `providers: [...]` of a component or directive or a module loaded with `loadChildren`, then there will be multiple instances. – Günter Zöchbauer Dec 27 '16 at 10:05
  • I'm using `loadChildren`. Is there someway to get my goal? – Jordi Dec 27 '16 at 10:24
  • Move the service out of the module loaded by `loadChildren` and add it to a module that is not lazy loaded. – Günter Zöchbauer Dec 27 '16 at 10:25
  • This is already injected on `AppModule`. It's not lazy loaded. How could I get it from a module created using `loadChildren`? – Jordi Dec 27 '16 at 10:31
  • If you provide it in `AppModule` **and** a module loaded using `loadChildren`, then to services and components loaded by the lazy loaded module the instance provided in the lazy loaded module will be injected and all other services and components will get the instance provided by `AppModule`. I don't think there is anything you can do about it. – Günter Zöchbauer Dec 27 '16 at 10:37
  • So then, the scope I've described previously would have to work, doesn't it? – Jordi Dec 27 '16 at 10:50
  • If it's only injected in `AppModule` and not in a module loaded with `loadChildren`, then there will always be only a single instance. – Günter Zöchbauer Dec 27 '16 at 10:51
  • Is there some way to load `Injectables` as singleton on `loadChildren`ed modules/components? – Jordi Dec 27 '16 at 10:57
  • Not one I'm aware of. Actually, I'm quite sure there isn't. See also http://stackoverflow.com/a/40981772/217408 – Günter Zöchbauer Dec 27 '16 at 10:58

0 Answers0