62

I am in reference to the router-store ngrx project (https://github.com/ngrx/router-store).

I am not clear how to use this project...

For instance let's take the following sample from the project documentation:

store.dispatch(go(['/path', { routeParam: 1 }], { query: 'string' }));

Is this meant to be use as a replacement to the angular 2 router: router.navigate(['/path...?

...or should I use the ngrx router-store only in certain circumstances? (if so which ones?)

Also what happens to the ngrx router-store when a angular 2 router html link e.g. <a routerLink="/heroes" is clicked?

More generally, can someone please explain what is achieved by the ngrx router-store project as compared to using the plain angular 2 router?

Or to rephrase, what does ngrx router-store brings in addition to the angular 2 router?

Edit: An interesting source of information and samples about ngrx is of course the ngrx example-app (https://github.com/ngrx/example-app).

I found a dependency to the router-store there but I have not been able to find where the router-store is used within the app...

FYI, here is the comment to be found in the example app about the router store:

@ngrx/router-store keeps router state up-to-date in the store and uses the store as the single source of truth for the router's state.

balteo
  • 23,602
  • 63
  • 219
  • 412

2 Answers2

90

The @ngrx/router-store exists so that it's possible for the store to be the single source of truth for an application's routing state.

Without it, there would be application state - the current route - not represented in the store. That means time-travel debugging using the DevTools would not be possible, as there would be no state in the store representing the route and there would be no actions representing route changes.

The router-store does not replace the Angular router; it just wires up listeners for routing actions and for the router itself.

When you emit a routing action using the go action creator, a "[Router] Go" action containing the specifed path is heard by the router-store which then calls the corresponding router method. When the router-store hears - from the router - that the route has changed it emits a "[Router] Update Location" action representing the route change and that action sees the router state in the store updated.

If, instead of using the go action creator, a routerLink is used to effect a route change, router-store will hear the change and will emit a "[Router] Update Location" action that will see the store's router state updated.

So, whether the route is changed via actions or more traditional links, the store always contains the router state.

With the "[Router] Update Location" actions representing route changes, you can undo said route changes via the DevTools - something that would not be possible if the router state were not represented in the store.

If you've not used the Redux DevTools, I would recommend you check them out:

cartant
  • 57,105
  • 17
  • 163
  • 197
  • 5
    Also, you might be interested to know that the Angular v3 router was based on the [`@ngrx/router`](https://github.com/ngrx/router) and was ["built together with the `@ngrx` team"](http://angularjs.blogspot.com.au/2016/06/improvements-coming-for-routing-in.html). – cartant Feb 04 '17 at 04:24
  • 6
    Do we remove it in production? if its use is only to help with the DevTools page transition or can it be used for other tasks – ramon22 Oct 07 '17 at 17:09
  • @ramon22: Did you get the ans for this ? – Shashank Vivek Jan 22 '18 at 19:40
  • I got the ans and stopped using it, if its only for Development but sticks around in production with no added benefit – ramon22 Jan 22 '18 at 21:09
  • 3
    I think there is more value than just TimeTravel debugging. See this Nrwl article: https://blog.nrwl.io/using-ngrx-4-to-manage-state-in-angular-applications-64e7a1f84b7b#7b4c – Ward Mar 18 '18 at 23:44
  • @ramon22 there are can be various usages of the router store, e.g. use in selectors. See: https://github.com/UltimateAngular/ngrx-store-effects-app/blob/8e859d1838d89fe833138e0a5a89ae0b0eebad3f/src/products/store/selectors/pizzas.selectors.ts#L24 – Yulian Sep 03 '18 at 09:13
  • 1
    I think it is worth mentioning that this answer is for @ngrx/router-store version 1.x, which is significantly different from the current version, 4.x. The router-store action creators such as `go` no longer exist as explained in this issue - https://github.com/ngrx/platform/issues/107 – Zach Gollwitzer Apr 22 '20 at 23:50
  • Good explanation. But given "whether the route is changed via actions or more traditional links, the store always contains the router state." what's the point of using their actions? Surely we should just use traditional routing (or this.router.navigate...) and the store will keep in sync? – Ben Taliadoros Aug 10 '22 at 10:31
  • Is `ngrx-store` necessary required? I think that makes things complicated. Can we just skip it? – Bigeyes Aug 10 '22 at 14:09
0

An example.

Say you have a selected id that you pass in the router state. That id references a customer.

Your url looks something like this: myapp.com/customers/7755664

When you route to the customer edit view, you can write a selector that gets the customer entity using the id from the router state. Say you want to scroll through the customers. You navigate to myapp.com/customers/7755653. The selector returns the customer, the select call emits and your view rerenders with the new customer.

It simplifies selectors and replaces the need to have a selectedcustomer property in your state.

Derek Kite
  • 1,767
  • 13
  • 15