Skip to content

Commit

Permalink
fix(router-plugin): remove initial navigation check
Browse files Browse the repository at this point in the history
  • Loading branch information
arturovt committed Aug 7, 2022
1 parent 07b1a05 commit f453a06
Showing 1 changed file with 1 addition and 68 deletions.
69 changes: 1 addition & 68 deletions packages/router-plugin/src/router.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import {
RouterStateSnapshot,
RoutesRecognized,
ResolveEnd,
UrlSerializer,
NavigationStart,
NavigationEnd
} from '@angular/router';
import { LocationStrategy, Location } from '@angular/common';
import { Action, Selector, State, StateContext, Store } from '@ngxs/store';
import { isAngularInTestMode } from '@ngxs/store/internals';
import { Subscription } from 'rxjs';
import { first } from 'rxjs/operators';

import {
Navigate,
Expand All @@ -39,12 +35,6 @@ export type RouterTrigger =
// The `devtools` trigger means that the state change has been triggered by Redux DevTools (e.g. when the time-traveling is used).
| 'devtools';

/**
* @description Will be provided through Terser global definitions by Angular CLI
* during the production build. This is how Angular does tree-shaking internally.
*/
declare const ngDevMode: boolean;

@State<RouterStateModel>({
name: 'router',
defaults: {
Expand Down Expand Up @@ -89,14 +79,10 @@ export class RouterState implements OnDestroy {
private _store: Store,
private _router: Router,
private _serializer: RouterStateSerializer<RouterStateSnapshot>,
private _ngZone: NgZone,
private _urlSerializer: UrlSerializer,
private _locationStrategy: LocationStrategy,
private _location: Location
private _ngZone: NgZone
) {
this.setUpStoreListener();
this.setUpRouterEventsListener();
this.checkInitialNavigationOnce();
}

ngOnDestroy(): void {
Expand Down Expand Up @@ -254,57 +240,4 @@ export class RouterState implements OnDestroy {
this._storeState = null;
this._routerState = null;
}

/**
* No sense to mess up the `setUpRouterEventsListener` method as we have
* to perform this check only once and unsubscribe after the first event
* is triggered
*/
private checkInitialNavigationOnce(): void {
// Caretaker note: we have still left the `typeof` condition in order to avoid
// creating a breaking change for projects that still use the View Engine.
if (
(typeof ngDevMode === 'undefined' || ngDevMode) &&
// Angular is running tests in development mode thus we can be sure that this method will be
// skipped in tests.
isAngularInTestMode()
) {
return;
}

const subscription = this._router.events
.pipe(first((event): event is RoutesRecognized => event instanceof RoutesRecognized))
.subscribe(({ url }) => {
// `location.pathname` always equals manually entered URL in the address bar
// e.g. `location.pathname === '/foo'`, but the `router` state has been initialized
// with another URL (e.g. used in combination with `NgxsStoragePlugin`), thus the
// `RouterNavigation` action will be dispatched and the user will be redirected to the
// previously saved URL. We want to prevent such behavior, so we perform this check

// `url` is a recognized URL by the Angular's router, while `currentUrl` is an actual URL
// entered in the browser's address bar
// `PathLocationStrategy.prototype.path()` returns a concatenation of
// `PlatformLocation.pathname` and normalized `PlatformLocation.search`.

// `Location.prototype.normalize` strips base href from the URL,
// if `baseHref` (declared in angular.json) for example is `/en`
// and the URL is `/test#anchor` - then `_locationStrategy.path(true)` will return `/en/test#anchor`,
// but `/en/test#anchor` is not known to the Angular's router, so we have to strip `/en`
// from the URL
const currentUrl = this._location.normalize(this._locationStrategy.path(true));
const currentUrlTree = this._urlSerializer.parse(currentUrl);
// We need to serialize the URL because in that example `/test/?redirect=https://google.com/`
// Angular will recognize it as `/test?redirect=https:%2F%2Fwww.google.com%2F`
// so we have to run the `currentUrl` via the `UrlSerializer` that will encode characters
const currentSerializedUrl = this._urlSerializer.serialize(currentUrlTree);

// If URLs differ from each other - we've got to perform a redirect to the manually entered URL
// in the address bar, as it must have a priority
if (currentSerializedUrl !== url) {
this._router.navigateByUrl(currentUrl);
}
});

this._subscription.add(subscription);
}
}

0 comments on commit f453a06

Please sign in to comment.