Reputation: 1592
Can services of child modules be shared with parent or sibling modules within Angular? If so, how?
App Module
\ Common Module
\ Core Module
\ Authentication Service
\ Event Handler Service
\ Logger Service
\ Data Service
\ Login Module
\ Dashboard Module
In the structure above, I want to declare Authentication, EventHandler, and Logger services in my Core module, etc.
My goal is for my services in Login and Dashboard modules to be able to use all of the services I created in Core. I do not want to re-declare all of those services in App, Login, or Dashboard (providers, etc.).
I've just finished watching several courses and they ALL stress registering the services in the App Module's providers array. Even though they created nested modules they NEVER mention the scenario above.
The courses I'm talking about are:
Angular: Getting Started by Deborah Kurata
Angular CLI by John Papa
Angular : First Look by John Papa
Upvotes: 3
Views: 841
Reputation: 60518
Have you gotten to the module in my course on "Angular Modules"? I cover this here:
Any service provider added to the providers array is registered at the root of the application. So the service is available to be injected into any class in the application.
And this example:
Say for example we have a feature module called ProductModule. We add the ProductService to the providers array of this module. At first glance, we may think that we have encapsulated the ProductService into the ProductModule. But that is not the case. Any service provider added to the providers array is registered at the root of the application and is available to any class, even classes in other feature modules.
Does the above cover your scenario as well?
And then this:
As discussed in the "Services and Dependency Injection" course module, there should only be one instance of a service that is an application-wide singleton. So a service should not be included in the providers array for any module that is meant to be shared. Instead, consider building a Core module for services and importing it once in the AppModule. This will help ensure that the services are only registered one time.
Let me know if this does not help and I'll look to clarify this further in the next update of my course.
Here is an example core module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { DataService } from './data.service';
import { MessageService } from './message.service';
@NgModule({
imports: [
CommonModule
],
declarations: [],
providers: [
DataService,
MessageService
]
})
export class CoreModule { }
I'm registering my DataService
and MessageService
here.
Then pull in the Core module like this:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { WelcomeComponent } from './home/welcome.component';
import { PageNotFoundComponent } from './home/page-not-found.component';
import { AppRoutingModule } from './app-routing.module';
/* Feature Modules */
import { UserModule } from './user/user.module';
import { MessageModule } from './messages/message.module';
import { CoreModule } from './core/core.module';
@NgModule({
declarations: [
AppComponent,
WelcomeComponent,
PageNotFoundComponent
],
imports: [
BrowserModule,
HttpClientModule,
UserModule,
MessageModule,
AppRoutingModule,
CoreModule
],
bootstrap: [AppComponent]
})
export class AppModule { }
Now the services registered in the CoreModule are available to every component, service, or other class in the entire application.
You use the service like this:
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../core/message.service';
@Component({
selector: 'pm-menu',
templateUrl: './menu.component.html'
})
export class MenuComponent implements OnInit {
get displayMessages(): boolean {
return this.messageService.displayMessages;
}
constructor(private messageService: MessageService) { }
// ...
}
To use anything in a code file you need to add an import statement for that thing. So you'll still need to add an import statement your services before you can use them in any component/class/pipe/service/etc that needs them.
Upvotes: 3
Reputation: 105497
It's important to understand that if you don't use lazy-loaded modules there's no hierarchy between modules. All modules and respective services are merged into single module factory which is then used to create a global injector.
With lazy-loaded modules you do get hierarchy but services from child modules can access services from the parent modules.
My goal is for my services in Login and Dashboard modules to be able to use all of the services I created in Core
So if your Core module is eagerly loaded, every service declared in the modules will be available throughout application.
The article Avoiding common confusions with modules in Angular explains this topic in depth.
Upvotes: 2