Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular, Central (Redux)'Store' vs Singleton Service, aka "what happened to separation of concerns"?

Tags:

angular

ngrx

As we're gearing up for our new Angular project, we are evaluating various architectural concepts to employ within our system--especially state management. In the past, there were natural complexities with client components being proactively notified. Today, enter reactive programming and central stores.

I understand the nature of maintaining a 'large' central store with corresponding actions (inside various services), reducers, and subscribers that contains state for the entire app. I also see the benefit of stratifying unit tests with these pure function reducers. The question I have is how does this stack up to the classic notions of 'separation of concerns' and 'single responsibility' where state is maintained for those components via their dedicated services (dependency injected) while a semblance of decoupling is provided as well?

Why use large central stores instead of singleton services that maintain 'contained' state who emit changes to subscribers AND maintain that separation of concerns (eg: customer data is separate from inventory data). Although, there are allusions to this in other parts of SO and the web, I don't see references directly tackling this question. Thoughts comparing these 2 notions (central store state vs dependency injected service/singleton state) and/or references that do is greatly appreciated.

like image 476
MoMo Avatar asked Mar 23 '17 20:03

MoMo


1 Answers

It's definitely a good start in your Angular journey to ask yourself that kind of questions about project architecture.

With AngularJs (v1.x) I didn't really know what was the best pattern to work in a reactive way and make sure every components could subscribe to a data somewhere in a service and if another component called the service to update some data, others components would update. Back then, I tried multiple solutions and ended up by adding RxJs to my project. It was probably overkill as I wasn't aware of RxJs super power and I basically didn't use any operator, I was just subscribing.

6~8 months ago, I discovered Redux and found this approach very interesting. I decided to dig more into that idea of centralized store, with pure functions and immutable data. It was one of the best choice as a web dev I've done. You can use Redux outside any framework. So even if I do have to make an example with JQuery and maintain quite an amount of data, I use Redux.

One thing I really like with Redux is to normalize my data and manipulate them like a database where a reducer manipulate a table for example. "Computed view" with selectors is also a powerful way of composing your data as you wish from raw "tables".


The question I have is how does this stack up to the classic notions of 'separation of concerns' and 'single responsibility' where state is maintained for those components via their dedicated services (dependency injected) while a semblance of decoupling is provided as well?

Well, as you tagged ngrx I can image that you plan to use it with Angular (v2 or +) and the separation of concern is great. You split your logic by Reducer for manipulating the tables, but how about making ajax calls for example ? For that kind of side effects, you should use ngrx/effects. So you'll still have your services + reducers. Effects will allow you to react to a dispatch for a given action.

For example, if you dispatch an action with the type FETCH_USER, in your reducer you simply toggle a boolean isFetchingUser to true (so you can display a spinner in your view maybe). Then from a user.effect.ts (which is a service), you can catch the FETCH_USER action and call your backend. Once the response has arrived, dispatch from the effect an action FETCH_USER_SUCCESS and pass the data from ajax call into the action payload.

If you want to take a look to some code, I've created a demo on Github called Pizza-Sync. It uses @ngrx/store and @ngrx/effects with normalized data.

If you've got the Chrome or Firefox Redux devtools extension, you can take a look into the store and the actions.

Hope it helps, let me know if you have further questions.

like image 178
maxime1992 Avatar answered Sep 28 '22 12:09

maxime1992