简体   繁体   中英

Can a lazy loaded module use a root injected canActivate guard?

I have a stackblitz books module with the following paths:

export const routes: Routes = [
  { path: 'find', component: FindBookPageComponent },
  { path: ':id', component: ViewBookPageComponent },
  { path: '', component: CollectionPageComponent },
];

Within the same app there is also a root injected AuthGuard service sitting in the services folder. If that guard is added to any of the routes in the books module, the application spins forever and will not launch.

Can a root injected CanActivate guard be used in a module without specifying it in the providers array of the module?

The documentation I have looked at show the guards being registered with the AppComponent providers , so I assumed that it would be ok to root inject the guards?

If it has to be specified, can it still be root injected?

The AuthGuard depends on a StateService and if it cannot be root injected, then neither can the StateService I assume?

Can a root injected CanActivate guard be used in a module without specifying it in the providers array of the module?

Technically it already is specified. The @Injectable({provideIn: 'root'}) tells the Angular compiler to add it to the main module's list of providers. It is just a convenience feature that was added to Angular.

The root module is the one defined by platformBrowserDynamic().bootstrapModule(module) in your entry TypeScript file (it's usually named main.ts ).

If that guard is added to any of the routes in the books module, the application spins forever and will not launch.

Sounds like the AuthGaurd returns an observable that does not complete. Try adding a return observable.pipe(first()); to the guard function.

All of the router features that use observables (canActive, canLoad, resolve, etc.) require that the observables complete.

The documentation I have looked at show the guards being registered with the AppComponent providers, so I assumed that it would be ok to root inject the guards?

In this case, the module is the same as the one where the root routes are declared. You can see that RouterModule.forRoot(appRoutes) is used to import the router with the top-level routes. So anything defined in the providers at this level will be seen by the router, because they both share the same injector.

The AuthGuard depends on a StateService and if it cannot be root injected, then neither can the StateService I assume?

If a provider has not been declared when the injector tries to instantiate a class, then you get a run-time error that the constructor has an unknown injectable. It's a message that looks something like this error: constructor(?) where the question mark is the unknown parameter.

This means that if StateService is defined as a provider later, then AuthGaurd will just fail to be started. This depends upon when AuthGaurd is first used, because they are not created until they are first used.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM