Skip to content

Upgrading @angular/router 11 to 12

Breaking11.2.14 → 12.2.17Breaking18Security1Platform59Deprecated1New36Changed20Fixed164Other14

BreakingUpgrade verdict

18 breaking changes and 17 platform requirement changes and a security fix.

  • Linked libraries no longer generate legacy i18n message ids; translations must be migrated with localize-migrate.
  • Drops support for Node v10.
  • The published packages no longer ship the compressed UMD bundle files.
  • Elements are now properly removed when the root view goes away, which can affect SSR HTML capture and tests that relied on leftover elements.
Top 5 of 37 that need code or config changes

Requires Node.js ^12.14.1 || >=14.0.0 from 12.1.0-next.3 (none stated before).

Breaking18
Linked libraries no longer generate legacy i18n message ids; translations must be migrated with localize-migrate.
localize-migrate
Drops support for Node v10.
Removes minified UMD bundles from distributed NPM packages.
Removes DOM elements correctly when the root view is removed in animations.
Linked libraries no longer generate legacy i18n message ids in compiler-cli.
localize-migrate
Changes default of emitDistinctChangesOnlyDefaultValue to true and deprecates emitDistinctChangesOnly.
emitDistinctChangesOnlyDefaultValueemitDistinctChangesOnlyQueryList.changes@ContentChildren@ViewChildren
Hardens attribute and property binding rules for iframe elements, requiring updates to existing iframe usages.
iframe
ng.getDirectives now returns an empty array for DOM nodes without an Angular context instead of throwing.
ng.getDirectives
PlatformLocation onPopState and onHashChange now return handler removal functions instead of void.
PlatformLocationPlatformLocation.onPopStatePlatformLocation.onHashChange
HttpParams methods accept string, number or boolean parameter values instead of only string.
HttpParams
ng.getDirectives returns an empty array for DOM nodes without Angular context instead of throwing.
ng.getDirectives
Changes APP_INITIALIZER token type to Promise<unknown> | Observable<unknown> | void.
APP_INITIALIZERInjector.getTestBed.injectProvider
Adds emitEvent option to FormArray and FormGroup methods.
FormGroup.addControlFormGroup.removeControlFormGroup.setControlFormArray.pushFormArray.insertemitEvent
FormArray.removeAt, setControl and clear now accept new options, so custom subclasses overriding them may need type-compatible updates.
FormArray.removeAtFormArray.setControlFormArray.clearFormArrayFormGroup
min and max attributes on number inputs now trigger min/max validation when a form directive is present.
minmaxformControlformControlNamengModel
XhrFactory moves from @angular/common/http to @angular/common, requiring import path updates.
XhrFactory
Strict null checks now report the router fragment as potentially null, requiring a null check.
RouterLinkActive.routerLinkActiveOptions input type is expanded, so code reading the property may need updating.
RouterLinkActive.routerLinkActiveOptions
Security1
Hardens attribute and property binding rules for iframe elements.
iframe
Platform17
Restricts the supported Node.js range for common to LTS versions only.
Updates the supported Node.js version range for common.
Restricts the language service supported Node versions to LTS releases only.
Updates the supported range of Node versions for animations to only include LTS versions.
Updates the supported Node.js version range for animations.
Updates the supported Node.js version range for bazel.
Updates the supported Node.js version range for common.
Updates the supported Node.js version range for compiler.
Updates the supported Node.js version range for compiler-cli.
Updates the supported range of Node.js versions for core.
Drops support for TypeScript 4.0 and 4.1.
Adds support for TypeScript 4.2.
Updates the supported range of Node.js versions for elements.
Updates the supported range of Node.js versions for forms.
Updates the supported range of Node.js versions for the language service.
Updates the supported range of Node.js versions for @angular/router.
Drops support for Node v10.
Deprecated1
Temporarily re-exports and deprecates XhrFactory.
XhrFactory

Generated by DepDelta from published .d.ts files. Not mixed with prose notes.

  • removed: type Navigation = { id: number; initialUrl: string | UrlTree; extractedUrl: UrlTree; finalUrl?: UrlTree; trigger: 'imperative' | 'popstate' | 'hashchange'; extras: NavigationExt…
  • changed: class RouterOutlet implements OnDestroy, OnInit → class RouterOutlet implements OnDestroy, OnInit, RouterOutletContract
  • changed: class ɵangular_packages_router_router_h → class ɵangular_packages_router_router_h implements OnDestroy
  • changed: constructor Router(rootComponentType: Type<any> | null, urlSerializer: UrlSerializer, rootContexts: ChildrenOutletContexts, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes) → constructor Router(rootComponentType: Type<any> | null, urlSerializer: UrlSerializer, rootContexts: ChildrenOutletContexts, location: Location_2, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Routes)
  • changed: function ɵangular_packages_router_router_f(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Route[][], opts?: ExtraOptions, urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy): Router → function ɵangular_packages_router_router_f(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, injector: Injector, loader: NgModuleFactoryLoader, compiler: Compiler, config: Route[][], opts?: ExtraOptions, urlHandlingStrategy?: UrlHandlingStrategy, routeReuseStrategy?: RouteReuseStrategy): Router
  • changed: function ɵangular_packages_router_router_k(): (typeof ɵangular_packages_router_router_h | { provide: InjectionToken<(() => void)[]>; multi: boolean; useFactory: typeof ɵangular_packages_router_router_i; deps: (typeof ɵangular_packages_router_router_h)[]; useExisting?: undefined } | { provide: InjectionToken<(compRef: ComponentRef<any>) => void>; useFactory: typeof ɵangular_packages_router_router_… → function ɵangular_packages_router_router_k(): ReadonlyArray<Provider>
  • changed: method ChildrenOutletContexts.onChildOutletCreated(childName: string, outlet: RouterOutlet): void → method ChildrenOutletContexts.onChildOutletCreated(childName: string, outlet: RouterOutletContract): void
  • changed: property ActivatedRoute.fragment: Observable<string> → property ActivatedRoute.fragment: Observable<string | null>
  • changed: property ActivatedRouteSnapshot.fragment: string → property ActivatedRouteSnapshot.fragment: string | null
  • changed: property OutletContext.outlet: RouterOutlet | null → property OutletContext.outlet: RouterOutletContract | null
  • changed: property RouterLinkActive.routerLinkActiveOptions: { exact: boolean } → property RouterLinkActive.routerLinkActiveOptions: { exact: boolean } | IsActiveMatchOptions
  • changed: readonly property Router.events: Observable<Event> → readonly property Router.events: Observable<Event_2>
  • added: interface IsActiveMatchOptions
  • added: interface Navigation
  • added: interface RouterOutletContract
  • added: method Router.isActive(url: string | UrlTree, matchOptions: IsActiveMatchOptions): boolean
  • added: method RouterOutletContract.activateWith(activatedRoute: ActivatedRoute, resolver: ComponentFactoryResolver | null): void
  • added: method RouterOutletContract.attach(ref: ComponentRef<unknown>, activatedRoute: ActivatedRoute): void
  • added: method RouterOutletContract.deactivate(): void
  • added: method RouterOutletContract.detach(): ComponentRef<unknown>
  • added: method ɵangular_packages_router_router_h.ngOnDestroy(): void
  • added: property IsActiveMatchOptions.fragment: 'exact' | 'ignored'
  • added: property IsActiveMatchOptions.matrixParams: 'exact' | 'subset' | 'ignored'
  • added: property IsActiveMatchOptions.paths: 'exact' | 'subset'
  • added: property IsActiveMatchOptions.queryParams: 'exact' | 'subset' | 'ignored'
  • added: property Navigation.extractedUrl: UrlTree
  • added: property Navigation.extras: NavigationExtras
  • added: property Navigation.finalUrl?: UrlTree
  • added: property Navigation.id: number
  • added: property Navigation.initialUrl: string | UrlTree
  • added: property Navigation.previousNavigation: Navigation | null
  • added: property Navigation.trigger: 'imperative' | 'popstate' | 'hashchange'
  • added: property RouterOutletContract.activateEvents?: EventEmitter<unknown>
  • added: property RouterOutletContract.activatedRoute: ActivatedRoute | null
  • added: property RouterOutletContract.activatedRouteData: Data
  • added: property RouterOutletContract.component: Object | null
  • added: property RouterOutletContract.deactivateEvents?: EventEmitter<unknown>
  • added: property RouterOutletContract.isActivated: boolean
  • changed: function setupTestingRouter(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location, loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][], opts?: ExtraOptions, urlHandlingStrategy?: UrlHandlingStrategy): Router → function setupTestingRouter(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][], opts?: ExtraOptions, urlHandlingStrategy?: UrlHandlingStrategy): Router
  • changed: function setupTestingRouter(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location, loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][], urlHandlingStrategy?: UrlHandlingStrategy): Router → function setupTestingRouter(urlSerializer: UrlSerializer, contexts: ChildrenOutletContexts, location: Location_2, loader: NgModuleFactoryLoader, compiler: Compiler, injector: Injector, routes: Route[][], urlHandlingStrategy?: UrlHandlingStrategy): Router