Skip to content

Commit

Permalink
refactor(router-state): change @Selector to createSelector (#2294)
Browse files Browse the repository at this point in the history
In this commit, we switch from using the selector decorator to allow it to be dropped in production
for apps that don't use it at all.

Breaking change: To get the `RouterState.state`, it is now required to call the `state`
function — `select(RouterState.state())`. Previously, it was possible to provide a generic type for
the router state, e.g., `select(RouterState.state<CustomRouterState>)`, but this is not possible
if `state` were a property.
  • Loading branch information
arturovt authored Jan 13, 2025
1 parent 56b9e7d commit 934d9e1
Show file tree
Hide file tree
Showing 7 changed files with 21 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ $ npm install @ngxs/store@dev
- Build(storage-plugin): Use `ngServerMode` to check whether we are in SSR [#2288](https://github.com/ngxs/store/pull/2288)
- Refactor(form-plugin): Replace `takeUntil` with `takeUntilDestroyed` [#2283](https://github.com/ngxs/store/pull/2283)
- Refactor(router-plugin): Reduce RxJS depedency [#2291](https://github.com/ngxs/store/pull/2291)
- Refactor(router-plugin): Change `@Selector` to `createSelector` [#2294](https://github.com/ngxs/store/pull/2294)

### 19.0.0 2024-12-3

Expand Down
4 changes: 2 additions & 2 deletions integration/app/list/list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export class ListComponent {
hello$ = this._store.select(ListState.getHello);
hello = this._store.selectSignal(ListState.getHello);

router$ = this._store.select<RouterStateSnapshot | undefined>(RouterState.state);
router = this._store.selectSignal<RouterStateSnapshot | undefined>(RouterState.state);
router$ = this._store.select<RouterStateSnapshot | undefined>(RouterState.state());
router = this._store.selectSignal<RouterStateSnapshot | undefined>(RouterState.state());

constructor(private _store: Store) {}
}
18 changes: 8 additions & 10 deletions packages/router-plugin/src/router.state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
NavigationEnd,
Event
} from '@angular/router';
import { Action, Selector, State, StateContext, StateToken, Store } from '@ngxs/store';
import { Action, createSelector, State, StateContext, StateToken, Store } from '@ngxs/store';
import {
NavigationActionTiming,
ɵNGXS_ROUTER_PLUGIN_OPTIONS
Expand Down Expand Up @@ -85,17 +85,15 @@ export class RouterState {

private _subscription!: Subscription;

@Selector()
static state<T = RouterStateSnapshot>(state: RouterStateModel<T>) {
// The `state` is optional if the selector is invoked before the router
// state is registered in NGXS.
return state?.state;
static state<T = RouterStateSnapshot>() {
return createSelector([ROUTER_STATE_TOKEN], (state: RouterStateModel<T>) => {
// The `state` is optional if the selector is invoked before the router
// state is registered in NGXS.
return state?.state;
});
}

@Selector()
static url(state: RouterStateModel): string | undefined {
return state?.state?.url;
}
static url = createSelector([ROUTER_STATE_TOKEN], state => state?.state?.url);

constructor() {
this._setUpStoreListener();
Expand Down
2 changes: 1 addition & 1 deletion packages/router-plugin/tests/issues/issue-1407.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ describe('#1407 issue', () => {

const document = injector.get(DOCUMENT);
const root = document.querySelector('app-root')!;
const routerState = store.selectSnapshot(RouterState.state);
const routerState = store.selectSnapshot(RouterState.state());

// Assert
expect(navigateDispatchedTimes).toBe(1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ describe('URL recognition in guards (https://github.com/ngxs/store/issues/1718)'
})
@Injectable()
class AppState {
@Selector([RouterState.state])
@Selector([RouterState.state()])
static getActiveRoute(route: RouterStateSnapshot): ActivatedRouteSnapshot {
let state: ActivatedRouteSnapshot = route.root;
while (state.firstChild) {
Expand Down
6 changes: 3 additions & 3 deletions packages/router-plugin/tests/router-data-resolved.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ describe('RouterDataResolved', () => {

constructor(store: Store) {
this.router$ = store.select(
RouterState.state
RouterState.state()
) as unknown as Observable<RouterStateModel>;
}
}
Expand Down Expand Up @@ -110,7 +110,7 @@ describe('RouterDataResolved', () => {
expect(dataFromTheOriginalRouter).toEqual({ test });

const dataFromTheRouterState = store.selectSnapshot<RouterStateSnapshot | undefined>(
RouterState.state
RouterState.state()
)!.root.firstChild!.data;
expect(dataFromTheOriginalRouter).toEqual(dataFromTheRouterState);
})
Expand Down Expand Up @@ -160,7 +160,7 @@ describe('RouterDataResolved', () => {
expect(dataFromTheOriginalRouter).toEqual({ test });

const dataFromTheRouterState = store.selectSnapshot<RouterStateSnapshot | undefined>(
RouterState.state
RouterState.state()
)!.root.firstChild!.data;
expect(dataFromTheOriginalRouter).toEqual(dataFromTheRouterState);
})
Expand Down
10 changes: 5 additions & 5 deletions packages/router-plugin/tests/router.plugin.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe('NgxsRouterPlugin', () => {
await ngZone.run(() => router.navigateByUrl('/testpath'));

// Assert
const routerState = store.selectSnapshot(RouterState.state)!;
const routerState = store.selectSnapshot(RouterState.state())!;
expect(routerState.url).toEqual('/testpath');

const routerUrl = store.selectSnapshot(RouterState.url);
Expand All @@ -57,7 +57,7 @@ describe('NgxsRouterPlugin', () => {
await store.dispatch(new Navigate(['a-path'])).toPromise();

// Assert
const routerState = store.selectSnapshot(RouterState.state);
const routerState = store.selectSnapshot(RouterState.state());
expect(routerState!.url).toEqual('/a-path');
})
);
Expand Down Expand Up @@ -92,7 +92,7 @@ describe('NgxsRouterPlugin', () => {

// Assert
const routerState = store.selectSnapshot(state =>
RouterState.state<RouterStateParams>(state.router)
RouterState.state<RouterStateParams>()(state.router)
);

expect(routerState!.url).toEqual('/a-path?foo=bar');
Expand Down Expand Up @@ -146,7 +146,7 @@ describe('NgxsRouterPlugin', () => {
.toPromise();

// Assert
const routerState = store.selectSnapshot(RouterState.state);
const routerState = store.selectSnapshot(RouterState.state());
expect(routerState!.url).toEqual('/route1?a=10&b=20');
expect(count).toBe(2);
})
Expand All @@ -166,7 +166,7 @@ describe('NgxsRouterPlugin', () => {

@Action(TestAction)
testAction(ctx: StateContext<unknown>) {
ctx.setState(this.store.selectSnapshot(RouterState.state));
ctx.setState(this.store.selectSnapshot(RouterState.state()));
}
}

Expand Down

0 comments on commit 934d9e1

Please sign in to comment.