Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get previous state from Router_Cancel in ngrx?

I was trying to restrict the user from navigating away from the current page by using CanDeactivate (if form is dirty and not saved). By the time we click on any link, Router_Navigation event is getting called and it is updating the router state in store and if I cancel the page navigation on modal pop up (from can deactivate), Router_Cancel event is being called, but the current router state is not getting updated (it’s still pointing to other page).

I saw this in ngrx documentation:

ROUTER_CANCEL and ROUTER_ERROR contain the store state before the navigation. Use the previous state to restore the consistency of the store.

Can someone please help me on how to get previous state from Router_cancel Action.

Thanks

like image 256
kumar Avatar asked Feb 08 '18 19:02

kumar


1 Answers

I solved this by creating an applicationRouter state to maintain current and previous routes, whenever ngrx router dispatches a ROUTER_NAVIGATION Event i am listening to it and updating my applicationRouterState.

At each point applicationRouter will have only two router events (current and previous state).

and whenever Router_Cancel is triggered i am toggling the previous router and current router state.

PFB, the soln:

@Effect()
    navigationListener$ = this.actions$.ofType('ROUTER_NAVIGATION')
        .pipe(
            switchMap((routerNavigationAction: RouterNavigationAction<RouterDefinition>) => {
                return of(routerNavigationAction).pipe(
                    withLatestFrom(this._routerNavigationData$),
                    map(([action, routerNavData]: [RouterNavigationAction<RouterDefinition>, RouterState]) => {
                        // TODO: Move this logic to Reducer
                        if (!(routerNavData.currentRouter && routerNavData.currentRouter.url
                            && routerNavData.previousRouter && routerNavData.previousRouter.url)) {
                            routerNavData.previousRouter = routerNavData.currentRouter =  action.payload.routerState;
                        } else {
                            routerNavData.previousRouter = routerNavData.currentRouter;
                            routerNavData.currentRouter = action.payload.routerState;
                        }
                        return new fromActions.MaintainPrevCurrRouterStateAction(routerNavData);
                    })
                );
            })
        );

And this is my state object:

export interface RouterDefinition {
    url: string;
    queryParams: Params;
    params: Params;
    segments: string[];
}
export interface RouterState {
    currentRouter: RouterDefinition;
    previousRouter: RouterDefinition;
}
like image 152
kumar Avatar answered Sep 24 '22 13:09

kumar