Marcel
Marcel

Reputation: 1142

How can I dispatch an NGRX action when query params of an URL change?

How would you dispatch a ngrx action when the query params of an URL change? I have an URL with parameters (for example http://myapp.my/documents?startdate=2015-04-04&enddate=2015-06-06 ) and when user clicks the back (forward) browser button, angular will navigate to the previous (next) URL which might have different search parameters. So I need to dispatch a "load documents" action to load corresponding docs from DB. I can see multiple ways to do it.

  1. I could bind a ngrx @Effect to the angular-router "navigationend" Observable and check if the URL matches "/documents". the effect would dispatch a load documents action

  2. I could bind an ngrx @Effect to ROUTER_NAVIGATION Action produced by ngrx/router-store and have a action. Problem here is that ROUTER_NAVIGATION does not guarantee that the user will really get to the intended page (for example they could be blocked by a route guard),

  3. I could dispatch the action inside canActivate() guard of the "documents" path - maybe other problems are hiding here (Edit: tested this and it does not work because canActivate is only called once. It is not called again when URL parameters change.)
  4. some better way?

Angular 5, ngrx 4.

Upvotes: 2

Views: 7007

Answers (2)

John
John

Reputation: 10069

You should use @ngrx/router-store to add the current route to the store, then you can subscribe to the current route params like

this.store.select('routerReducer', 'state', 'params').subscribe(params => {
  // do stuff
})

select should automatically de-duplicate params for you, ensuring that you only dispatch actions when the route params change. You can also modify this to make use of .pipe(), if appropriate. Or make an @Effect() that watches the router and does stuff. @ngrx/router-store has solutions for all of this.

Version 4.1.1 docs <-- edit: these docs are now outdated

Upvotes: 6

Sandip Jaiswal
Sandip Jaiswal

Reputation: 3720

Use following code:

this.route.params.subscribe(param: ParamMap => {
  // dispatched your action to fetch data
  this.store.dispatch(new YourAction.YourActionMethod());
  // When your store will update then subscribe will fired
  this.store.select(reducers.YourReducer).subscribe((data) => {
    if (data) {
      // use your data here
    }
  });
});

Hope it will help

Upvotes: -2

Related Questions