* Schedules a router navigation to synchronize Router state with the browser state. * * This is done as a response to a popstate event and the initial navigation. These * two scenarios represent times when the browser URL/state has been updated and * the Router needs to respond to ensure
(
url: string,
source: NavigationTrigger,
state: RestoredState | null | undefined,
extras: NavigationExtras,
)
| 302 | * the Router needs to respond to ensure its internal state matches. |
| 303 | */ |
| 304 | private navigateToSyncWithBrowser( |
| 305 | url: string, |
| 306 | source: NavigationTrigger, |
| 307 | state: RestoredState | null | undefined, |
| 308 | extras: NavigationExtras, |
| 309 | ) { |
| 310 | // TODO: restoredState should always include the entire state, regardless |
| 311 | // of navigationId. This requires a breaking change to update the type on |
| 312 | // NavigationStart’s restoredState, which currently requires navigationId |
| 313 | // to always be present. The Router used to only restore history state if |
| 314 | // a navigationId was present. |
| 315 | |
| 316 | // The stored navigationId is used by the RouterScroller to retrieve the scroll |
| 317 | // position for the page. |
| 318 | const restoredState = state?.navigationId ? state : null; |
| 319 | |
| 320 | // When `browserUrl` was used during the original navigation, the actual route URL |
| 321 | // was stored in history state as `ɵrouterUrl`. Use it for route matching and |
| 322 | // preserve the browser URL as the displayed URL. |
| 323 | const routerUrl = state?.ɵrouterUrl ?? url; |
| 324 | if (state?.ɵrouterUrl) { |
| 325 | extras = {...extras, browserUrl: url}; |
| 326 | } |
| 327 | |
| 328 | // Separate to NavigationStart.restoredState, we must also restore the state to |
| 329 | // history.state and generate a new navigationId, since it will be overwritten |
| 330 | if (state) { |
| 331 | const stateCopy = {...state} as Partial<RestoredState>; |
| 332 | delete stateCopy.navigationId; |
| 333 | delete stateCopy.ɵrouterPageId; |
| 334 | delete stateCopy.ɵrouterUrl; |
| 335 | if (Object.keys(stateCopy).length !== 0) { |
| 336 | extras.state = stateCopy; |
| 337 | } |
| 338 | } |
| 339 | |
| 340 | const urlTree = this.parseUrl(routerUrl); |
| 341 | this.scheduleNavigation(urlTree, source, restoredState, extras).catch((e) => { |
| 342 | if (this.disposed) { |
| 343 | return; |
| 344 | } |
| 345 | this.injector.get(ɵINTERNAL_APPLICATION_ERROR_HANDLER)(e); |
| 346 | }); |
| 347 | } |
| 348 | |
| 349 | /** The current URL. */ |
| 350 | get url(): string { |
no test coverage detected