universal: Guards and Resolvers don't wait for APP_INITIALIZER, if RouterModule initialNavigation: 'enabled' is set
š bug report
Affected Package
@angular/router/RouterModule @angular/core/APP_INITIALIZER
Is this a regression?
Yes, this used to work all the way up until Angular 8.2.14. This bug started to appear once I updated to Angular 9 (9.0.7) EDIT: I updated to Angular 9.1, but the problem persists.
Description
After Upgrading I noticed, that some parts of my application wouldnāt start any longer, because the configuration they are depending on is empty.
I used to load this configuration from a config file on my server. Iām using APP_INITIALIZER for this. Upon further investigation I found out, that my guards and resolvers run before my APP_INITIALIZER promise resolves.
Finally I could pin-point this error to app-routing.module.ts. When I uncomment initialNavigation: 'enabled'
then the guards and resolvers wait till the APP_INITIALIZER promise resolve.
Once enabled, the guards and resolvers run immediately and donāt wait for APP_INITIALIZER.
@NgModule({
imports: [
RouterModule.forRoot(routes, {
// initialNavigation: 'enabled'
})
],
exports: [RouterModule]
})
export class AppRoutingModule { }
š¬ Minimal Reproduction
Open the console to see when different parts of the application get executed. MinimalGuard and ResolverService should get executed after AppInitializerService Promise resolved, but unfortunately they get executed before.
https://stackblitz.com/github/felixfiskare/ResolverAndGuardBeforeInit
https://github.com/felixfiskare/ResolverAndGuardBeforeInit
š„ Exception or Error
š Your Environment
Angular Version:
ng version
_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ ā³ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/
Angular CLI: 9.0.7
Node: 13.11.0
OS: linux x64
Angular: 9.0.7
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.7
@angular-devkit/build-angular 0.900.7
@angular-devkit/build-optimizer 0.900.7
@angular-devkit/build-webpack 0.900.7
@angular-devkit/core 9.0.7
@angular-devkit/schematics 9.0.7
@ngtools/webpack 9.0.7
@schematics/angular 9.0.7
@schematics/update 0.900.7
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Reactions: 12
- Comments: 22 (2 by maintainers)
@felixfiskare This is caused by the NgUniversal schematics, we added it to avoid flicker when bootstrapping on the client. Weāll move this issue over to angular/universal so that we can track a proper resolution. This may be a warning or a prompt, or possibly a link to documentation about certain pitfalls with adding
initialNavigation
, like the one you encountered here.Iāve looked into the docs and the
router_module
and determined that guards and resolvers being run before the userās ownAPP_INITIALIZER
is working as intended.APP_INITIALIZER
.APP_INITIALIZERS
are run in parallel.initialNavigation: 'enabled'
the routerāsAPP_INITIALIZER
triggers a navigation. This means that if your initial navigation depends on your ownAPP_INITILIZER
being completed first, you cannot useinitialNavigation: 'enabled'
.ApplicationRef.bootstrap
(which happens afterAPP_INITIALIZER
completion) calls allAPP_BOOTSTRAP_LISTENER
s, which triggers initial navigation if usinginitialNavigation: 'legacy_enabled'
That said, if
initialNavigation: 'enabled'
was added automatically when upgrading as you say, this is a bug in the migration since theinitialNavigation
options are not equivalent.Hi, any update of when is this going to be merged? Thanks!
Hi guys, hereās the workarounds Iām applying on my project (v11). It works with SRR as well. Hope it helps someone
userInfoSubject
to inform the authentication statususerInfoSuject.next(userInfo)
. Note that whenever theuserInfo
changes (by sign in, sign upā¦) we need to emit the authentication status too@nils-thomann, I believe that really depends on your project. For example, in my project I have dynamic routes, which I only know by doing an API Call. So now I have a few assumptions in my routes (so, now itās not 100% dynamic, but like 80%) and I have a Resolver that makes the same call that I used to do in APP_INITIALIZER.
Yep, same issue here. I āresolvedā by adding an āif isPlatformBrowser(this.platformId)ā in each guardā¦
Hi, Iām facing the same issue here too