Skip to content

Commit

Permalink
fix(router): Ensure renavigating in component init works with enabled…
Browse files Browse the repository at this point in the history
…Blocking

The correct property to check if the subject has completed is
`isStopped` rather than `isClosed`. This issue fixes returning the
subject again when it has already emitted (and won't emit again).

fixes #48052
  • Loading branch information
atscott committed Nov 15, 2022
1 parent 954f700 commit 912afc4
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 2 deletions.
2 changes: 1 addition & 1 deletion packages/router/src/provide_router.ts
Expand Up @@ -366,7 +366,7 @@ export function withEnabledBlockingInitialNavigation(): EnabledBlockingInitialNa
resolve(true);
// only the initial navigation should be delayed until bootstrapping is done.
if (!initNavigation) {
return bootstrapDone.closed ? of(void 0) : bootstrapDone;
return bootstrapDone.isStopped ? of(void 0) : bootstrapDone;
// subsequent navigations should not be delayed
} else {
return of(void 0);
Expand Down
51 changes: 50 additions & 1 deletion packages/router/test/bootstrap.spec.ts
Expand Up @@ -11,7 +11,7 @@ import {ApplicationRef, Component, CUSTOM_ELEMENTS_SCHEMA, destroyPlatform, Inje
import {inject} from '@angular/core/testing';
import {BrowserModule} from '@angular/platform-browser';
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
import {NavigationEnd, provideRouter, Resolve, Router, RouterModule, withEnabledBlockingInitialNavigation} from '@angular/router';
import {NavigationEnd, provideRouter, Resolve, Router, RouterModule, RouterOutlet, withEnabledBlockingInitialNavigation} from '@angular/router';

// This is needed, because all files under `packages/` are compiled together as part of the
// [legacy-unit-tests-saucelabs][1] CI job, including the `lib.webworker.d.ts` typings brought in by
Expand Down Expand Up @@ -112,6 +112,55 @@ describe('bootstrap', () => {
});
});

it('should finish navigation when initial navigation is enabledBlocking and component renavigates on render',
async () => {
@Component({
template: '',
standalone: true,
})
class Renavigate {
constructor(router: Router) {
router.navigateByUrl('/other');
}
}
@Component({
template: '',
standalone: true,
})
class BlankCmp {
}

let resolveFn: () => void;
const navigationEndPromise = new Promise<void>(r => {
resolveFn = r;
});

@NgModule({
imports: [BrowserModule, RouterOutlet],
declarations: [RootCmp],
bootstrap: [RootCmp],
providers: [
{provide: LocationStrategy, useClass: HashLocationStrategy},
provideRouter(
[{path: '', component: Renavigate}, {path: 'other', component: BlankCmp}],
withEnabledBlockingInitialNavigation())
],
})
class TestModule {
constructor(router: Router) {
router.events.subscribe(e => {
if (e instanceof NavigationEnd) {
resolveFn();
expect(router.url).toEqual('/other');
}
});
}
}

await Promise.all(
[platformBrowserDynamic([]).bootstrapModule(TestModule), navigationEndPromise]);
});

it('should wait for redirect when initialNavigation = enabledBlocking', async () => {
@Injectable({providedIn: 'root'})
class Redirect {
Expand Down

0 comments on commit 912afc4

Please sign in to comment.