user11472365
user11472365

Reputation:

How to use NGRX Routers correctly?

I honestly was totally lost by the documentation, and besides I was wondering the following:

If I use the NGRX Router, will I need to use the angular's native app-rounting? If so, how do I integrate the NGRX Router with the <router-outlet>?

Could you give me a simple example of the same?

Upvotes: 1

Views: 4317

Answers (1)

Hamza Zaidi
Hamza Zaidi

Reputation: 672

Angular Router and NGRX router work together. Angular Router is responsible for actual routing in the application and NGRX router is responsible for getting the information out from the Angular router, following is the simple example to use navigation without NGRX.

@Injectable()
export class SomeComponent {
  constructor(private router: Router) {}
  /*
  Your Component code  
  */
  onSubmit() {
    this.router.navigate(['/some-url'])
  }

}

Follow the NGRX Router documentation to setup the store.

following is the way to use Angular routing with NGRX

router.action.ts (dispatch actions from components for navigation to happen)

import { createAction, props } from '@ngrx/store';
import { NavigationExtras } from '@angular/router';

export enum RouterActionTypes {
  Go = '[Router] Go',
  Back = '[Router] Back'
}

export const Go = createAction(RouterActionTypes.Go, props<{ payload: { path: any[]; query?: object; extras?: NavigationExtras } }>());

export const Back = createAction(RouterActionTypes.Back);

router.effect.ts (Effect handle the side effects, it catches the navigation action dispatch from component and does the actual routing)

import { Location } from '@angular/common';
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { tap, map } from 'rxjs/operators';
import * as RouterActions from '../actions/router.actions';

@Injectable()
export class RouterEffects {
  constructor(private actions$: Actions, private router: Router, private location: Location) {}

  navigate$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(RouterActions.Go),
        map((action) => action.payload),
        tap(({ path, query: queryParams, extras }) => {
          this.router.navigate(path, { queryParams, ...extras });
        }),
      ),
    { dispatch: false },
  );

  navigateBack$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(RouterActions.Back),
        tap(() => this.location.back()),
      ),
    { dispatch: false },
  );
}

NGRX provides build in Selectors to get the routing information for example queryParams, url etc.

for example you have to get the list of user by department and departmentId is in the query param of the URL

https://localhost:4200/users?deparmentId=4

Right way to read the query param is through selectQueryParams selector provided by NGRX library

export const selectSelectedDepatmentId = selectQueryParam('deparmentId');

export const selectUsersByDepartment = createSelector(
   selectUsers,
   selectSelectedDepatmentId,
   (users, departmentId) => users.filter(u => u.departmentId === departmentId)
);

Upvotes: 3

Related Questions