-
Notifications
You must be signed in to change notification settings - Fork 27k
Description
Which @angular/* package(s) are relevant/releated to the feature request?
router
Description
Rendering an app in SSR (using nguniversal) with an invalid URL (e.g. http://localhost:4200/electronics-spa/en/USD/Brands/Canon/c/brand_10%20or%20(1,2)=(select*from(select%20name_const(CHAR(82,88,106,99,113,78,74,70,73,118,87),1),name_const(CHAR(82,88,106,99,113,78,74,70,73,118,87),1))a)%20--%20and%201%3D1) causes the render to hang, and never release the taken resources.
The reason is that the navigation never completes on error, when the Router option initialNavigation is set to enabled.
Proposed solution
Expose RouterInitializer.
EDIT: or make the router complete the navigation on error, if that makes sense.
Alternatives considered
We came up with this workaround, but it would be nice if ɵangular_packages_router_router_h could be exposed.
import { Injectable, Injector, Provider } from '@angular/core';
import {
NavigationError,
Router,
ROUTER_CONFIGURATION,
ɵangular_packages_router_router_h as RouterInitializer,
} from '@angular/router';
import { filter, take } from 'rxjs/operators';
@Injectable()
export class CustomRouterInitializer extends RouterInitializer {
appInitializer(): Promise<any> {
const injector: Injector = (this as any).injector;
const opts = injector.get(ROUTER_CONFIGURATION);
if (
opts.initialNavigation ===
'enabled' /* for Ng11: || opts.initialNavigation === 'enabledBlocking' */
) {
let resolve: any;
const res = new Promise((r) => (resolve = r));
injector
.get(Router)
.events.pipe(
// We want to explicitly react on NavigationError event occurs just
// after the first navigation start event
take(2),
filter((event) => event instanceof NavigationError)
)
.subscribe(() => resolve(false));
super.appInitializer().then((val) => resolve(val));
return res;
}
return super.appInitializer();
}
}
export const routerFixProvider: Provider = {
provide: RouterInitializer,
useClass: CustomRouterInitializer,
};The above workaround is for ng12.
I noticed that in ng13 there's no similar private API available, unless I'm missing something.