fix(router): prevent calling unsubscribe on undefined subscription in RouterPreloader (#38344)
Previously, the `ngOnDestroy` method called `unsubscribe` regardless of if `subscription` had been initialized. This can lead to an error attempting to call `unsubscribe` of undefined. This change prevents this error, and instead only attempts `unsubscribe` when the subscription has been defined. PR Close #38344
This commit is contained in:
parent
ba175be41f
commit
763023472b
@ -74,8 +74,7 @@ export class NoPreloading implements PreloadingStrategy {
|
|||||||
@Injectable()
|
@Injectable()
|
||||||
export class RouterPreloader implements OnDestroy {
|
export class RouterPreloader implements OnDestroy {
|
||||||
private loader: RouterConfigLoader;
|
private loader: RouterConfigLoader;
|
||||||
// TODO(issue/24571): remove '!'.
|
private subscription?: Subscription;
|
||||||
private subscription!: Subscription;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private router: Router, moduleLoader: NgModuleFactoryLoader, compiler: Compiler,
|
private router: Router, moduleLoader: NgModuleFactoryLoader, compiler: Compiler,
|
||||||
@ -98,12 +97,11 @@ export class RouterPreloader implements OnDestroy {
|
|||||||
return this.processRoutes(ngModule, this.router.config);
|
return this.processRoutes(ngModule, this.router.config);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(jasonaden): This class relies on code external to the class to call setUpPreloading. If
|
|
||||||
// this hasn't been done, ngOnDestroy will fail as this.subscription will be undefined. This
|
|
||||||
// should be refactored.
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
|
if (this.subscription) {
|
||||||
this.subscription.unsubscribe();
|
this.subscription.unsubscribe();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private processRoutes(ngModule: NgModuleRef<any>, routes: Routes): Observable<void> {
|
private processRoutes(ngModule: NgModuleRef<any>, routes: Routes): Observable<void> {
|
||||||
const res: Observable<any>[] = [];
|
const res: Observable<any>[] = [];
|
||||||
|
@ -19,6 +19,23 @@ describe('RouterPreloader', () => {
|
|||||||
class LazyLoadedCmp {
|
class LazyLoadedCmp {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
describe('should properly handle', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [RouterTestingModule.withRoutes(
|
||||||
|
[{path: 'lazy', loadChildren: 'expected', canLoad: ['someGuard']}])],
|
||||||
|
providers: [{provide: PreloadingStrategy, useExisting: PreloadAllModules}]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('being destroyed before expected', () => {
|
||||||
|
const preloader: RouterPreloader = TestBed.get(RouterPreloader);
|
||||||
|
// Calling the RouterPreloader's ngOnDestroy method is done to simulate what would happen if
|
||||||
|
// the containing NgModule is destroyed.
|
||||||
|
expect(() => preloader.ngOnDestroy()).not.toThrow();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('should not load configurations with canLoad guard', () => {
|
describe('should not load configurations with canLoad guard', () => {
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [LazyLoadedCmp],
|
declarations: [LazyLoadedCmp],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user