3

I have a lazy-loaded-module with a root and child componets. I also have a service to share data between the root and the child components and siblings.

The use case behind is a wizard, where the user can set some data in multiple steps. The data of each step is stored globally in the service, so that the parent and every child component is able to access the whole data.

Now i want to create guards for the single steps, which should check if the step before was done (data in the service is set) to prevent the user from accessing further steps by URL without doing the steps before.

Module

@NgModule({
imports: [
    CommonModule,
    FormsModule,
    AppointmentAgreementRouting
],
declarations: [
    AppointmentAgreementComponent,
    TopicSectionComponent,
    BranchSectionComponent,
    DatetimeSectionComponent,
    PersonalDataSectionComponent,
    ConfirmationSectionComponent,
    SectionDirective
],
providers: [
    CanActivateBranch, <-- Guard which should check if the data is set in service
    { provide: 'components', useValue: [AppointmentAgreementComponent], multi: true }
],
entryComponents: [
    AppointmentAgreementComponent,
    TopicSectionComponent,
    BranchSectionComponent,
    DatetimeSectionComponent,
    PersonalDataSectionComponent,
    ConfirmationSectionComponent
]
})

Routing

const appointmentAgreementRoutes: Routes = [{
path: '',
children: [
    {path: '', redirectTo: 'thema', pathMatch: 'full'},
    {path: 'thema', component: TopicSectionComponent},
    {path: 'filiale', component: BranchSectionComponent, canActivate: [CanActivateBranch]},
    {path: 'termin', component: DatetimeSectionComponent},
    {path: 'daten', component: PersonalDataSectionComponent},
    {path: 'bestaetigung', component: ConfirmationSectionComponent},
]
}];

Root-Component

@Component({
selector: 'appointment-agreement',
templateUrl: './appointmentAgreement.component.html',
providers: [
    AppointmentAgreementCommunicationService <-- Service to share data
]
})

My problem now is, that i am providing the service in the root component, because i need the same service instance for every of these components (root and childs).

But i need to provide the guard in the module, because otherwise i am getting "No provider found for CanActivateBranch (guard)"

If i want to inject the service now into the guard, i am getting "No provider for ...service" because the service is just provided in the component and not in the module.

Does anybody has an idea how to solve this problem?

Thanks a lot in advance.

Rohan Fating
  • 2,135
  • 15
  • 24
user3507003
  • 359
  • 4
  • 17
  • why you want to provide service in component is there any specific use case. Else if you provide data sharing service in module then this problem will be solved – Prathmesh Dali Aug 28 '17 at 14:57
  • read [Avoiding common confusions with modules in Angular](https://blog.angularindepth.com/avoiding-common-confusions-with-modules-in-angular-ada070e6891f) – Max Koretskyi Aug 28 '17 at 16:05
  • Can you remove the service from the root component and just provide it in the module? And what is the purpose of all of those entryComponents? – DeborahK Aug 28 '17 at 22:44
  • From the docs: `Angular automatically adds the following types of components to the module's entryComponents: (1) The component in the @NgModule.bootstrap list. (2) Components referenced in router configuration.` So since these components are part of routes, they are not needed also in the `entryComponents`. See this link: https://angular.io/guide/ngmodule-faq#what-is-an-entry-component – DeborahK Aug 28 '17 at 23:21
  • Thanks for your comments. The problem were these unneeded entry components. By removing them i can now provide the service in the module. But now i have another little problem, please see the update in my question. – user3507003 Aug 29 '17 at 05:53
  • Take a look at [this answer](https://stackoverflow.com/questions/39653072/how-to-use-forroot-within-feature-modules-hierarchy/39653824#39653824) explaining `.forRoot()`, it may assist. – P. Moloney Aug 29 '17 at 12:40
  • Hmm, i tried to provide the service and the guard in the forRoot of the module, but then i get "No provider for CanActivateBranch". Also this answer sounds for me like this topic is about sharing services between modules. But what i want is, to share a service between components and guard inside one module. Any other ideas? – user3507003 Aug 30 '17 at 09:53
  • 1
    Really good question IMO. I'm facing the same issue. If you found something, please tell us. Also, it's important the guard is using the same service than the "component shared" one, as the service can be stateful. – R. G Dec 29 '17 at 14:58

0 Answers0