How to maintain parameters with ngrx/router-store

2.3k Views Asked by At

I have some parameters that I need to put to some of my pages, which means when these pages are visited, I want to check if they are in ngrx store or not, and use them if they are. One more rule for this is that if they exist in URL, use them and replace the ones in ngrx store.

So the order is like:

  1. use the ones from URL if there's any
  2. use the ones from ngrx store if there's any
  3. mark them as empty if there's none

I found it's easy to implement with just type script, but I don't know what should I pass as paramters with <a> element and routerLink.

Is there a way to say when RouterActions.Go is called, check if there are some parameters already in ngrx store?

1

There are 1 best solutions below

4
On

Sure there is an easy way. Just make an effects proxy for handling routing actions and use the router just like any other NGRX-effects:

@Injectable()
export class RouterEffects {
  @Effect({ dispatch: false })
  navigate$ = this.actions$.ofType(RouterActions.GO)
    .map((action: RouterActions.Go) => action.payload)
    .do((routerPayload: RouterPayload) => {
      this.router.navigate(routerPayload.path, routerPayload.query);
  });

  @Effect({ dispatch: false })
  navigateBack$ = this.actions$.ofType(RouterActions.BACK)
    .do(() => this.location.back());

  @Effect({ dispatch: false })
  navigateForward$ = this.actions$.ofType(RouterActions.FORWARD)
    .do(() => this.location.forward());

  constructor(
    private actions$: Actions,
    private router: Router,
    private location: Location
  ) {}
}

with the router.actions.ts:

export const GO = '[Router] Go';
export const BACK = '[Router] Back';
export const FORWARD = '[Router] Forward';

export interface RouterPayload {
  path: string[];
  query?: NavigationExtras;
}

export class Go implements Action {
  readonly type = GO;
  constructor(public payload: RouterPayload) {}
}

export class Back implements Action {
  readonly type = BACK;
}

export class Forward implements Action {
  readonly type = FORWARD;
}

export type Actions
  = Go
  | Back
  | Forward;

and in your component you dispatch router actions on navigation instead of calling routerLink directly in the template:

navigate(routerPayload: RouterPayload) {
  this.store.dispatch(new RouterActions.Go(routerPayload));
}

This way you can also easily go back and forth in your routes.