State management is one of the most difficult tasks in front-end development. In Angular2 we are presented with a number of options. The most promising ones seem to be holding reusable state in services vs. using the ngrx/store library specifically designed to help with state management. Here are my current views on the pros and cons of each approach, prioritized:

Pros of using ngrx/store

1. Dev Tools
2. You have a clear methodology => Other people joining your project will know how to handle state if they know ngrx (or redux or similar), and if not, they know where to inform themselves.

Cons of using ngrx/store

1. You’re adding an extra library. Could become deprecated, badly maintained or have breaking changes all the time. For example, we couldn’t update our project to Angular 5, because ngrx was lagging behind. Also, updating from ngrx/store v2 to nrgrx/store v4 took one afternoon, and that was for a small project.
2. Name-spacing is ugly, e.g. '[heroes] UPDATE'. What happens if you choose the same action name by accident? The answers  aren’t really satisfying. With services you’ll get better autocompletion: heroService.updateHero(hero) instead of dispatch({type: '[heroes] UPDATE', hero}). Of course you could put the dispatch also in a heroService, but then you’ll have more boilerplate.

Pros of using services as your store

1. No extra library needed, it’s core Angular
2. You don’t have one global state, so you can better modularize. For example you can have a reusable UserModule, that doesn’t know anything about the other parts of the state of your app.
3. No name-spacing problems as every resource has it’s own service
4. Complete flexibility in use. You can throw immutability overboard, if you want.

Cons of using services as your store

1. No-one tells you how to do it, no standards

Conclusion

I still prefer the manual approach with services. I think it adds a lot to the flexibility and simplicity that you can shape your data-store as you need it. Often you don’t need the entire store store to be an observable and you can easily extend your store-services to make them observables once you need that feature. For example I’d rather have a store with the signature

heroStore: {[heroId: string]: BehaviorSubject<Hero>}

than the signature

heroStore: BehaviorSubject<{[heroId: string]: Hero}>

As long as I don’t need something like the total number of heroes it’s completely sufficient to have the first signature. And in case I suddenly need the store as an observable in my app, I can still easily change the service.

Also the mistakes in the docs and an example-app that’s far from real-world scare me a bit.

Join the Conversation

1. Anonymous says:

so wrong

1. bersling says:

mind to elaborate?

2. Mike says:

I absolutely agree with you. Well done!

I tried it and it’s ONLY good for someone using javascript and not an advanced language like angular 2

3. bastien says:

I also go with the shared/singleton services without using observables because in 99% of the cases you do not need them to react to changes

4. James Trefry says:

Here are some other pros of NgRx or NGXS (less boilerplate).

* You can hydrate your entire application with a single JSON object – useful for debugging, testing, or returning the user to the exact state they had previously.
* Single point of entry allows complete logging and interception/filtering/modification of actions.
* A standard for state management allows the community to provide useful plugins. https://ngxs.gitbook.io/ngxs/plugins

I think services are best for simple apps, but as complexity grows, you will be wishing you had controls to reign in the resulting chaos.

1. bersling says:

What I’ve experienced was the exact opposite. It sounds nice in theory what ngrx has to offer, but ngrx has added so much boilerplate and indirection to our code, that it is really hard to refactor anything.

5. mean.studio says:

Despite common opinion, ngrx gets hard to maintain and I have seen a lot of spaghetti code which triggers each other and it gets really messy.
Despite people assumes that there is only one way to set up ngrx/redux, I have seen tons of different ways which all of then end up to be faulty and need to be rewritten from scratch.
Ngrx uses a lot of boilerplate code which is not necessary for most of cases.
Some concepts like reducers are totally wrong. In apps I always see list of items, merely I need to apply something to single item. Mappers and filters are good in case you need transform all or portion of data.

1. bersling says:

I totally agree