Angular singleton services shared between library and app

Viewed 562

I am developing a library with some singleton services that should be used both by the app that imports the library and by components in the library as well. What I've done:

1)Create a CoreServicesModule with the forRoot method. In the example the method takes an environment parameter which is used in some of these services.

export class CoreServicesModule {
    constructor(@Optional() @SkipSelf() parentModule?: CoreServicesModule) {
        if (parentModule) {
            throw new Error('CoreServicesModule is already loaded. Import it in the AppModule only');
        }
    }

    public static forRoot(environment: any): ModuleWithProviders<CoreServicesModule> {
        return {
            ngModule: CoreServicesModule,
            providers: [
                BaseSingletonService,
                BaseSingletonService2,
                {
                    provide: 'environment',
                    useValue: environment
                }
            ]
        };
    }
}

2)In the application I've injected the service in the component's constructor. I have NOT included the CoreServicesModule in my LibraryComponentModule, where this component is declared.

import { BaseSingletonService } from "@myorg/library/src/library/services";
@Component({
  selector: "library-component",
  templateUrl: "./library-component.component.html",
  styleUrls: ["./library-component.component.scss"],
})
export class LibraryComponent {
  constructor(private baseSingletonService: BaseSingletonService) {}
}

3)Imported the CoreServicesModule inside the application's app.module.ts

@NgModule({
    imports: [
      //...
    CoreServicesModule.forRoot(environment)
  ],
  providers: [],
  declarations: [
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Inside the application everything is working as expected. However when I use the library-component I get the NullInjectorError: No provider for BaseSingletonService error. What am I missing? How do you share singleton services between angular library and application?

1 Answers

What worked for me was to

  1. Do the forRoot() method AND
  2. Declare the service with providedIn: 'platform'

Just doing one of those without the other didn't seem to do it for me.

My other note is that it could be the order of the modules in your app.module.ts. If you import LibraryComponentModule before CoreServicesModule, the providers that LibraryComponentModule needs won't yet be provided.

Related