State management or Observable services
State management or Observable services ? All right, all right. We got it. Everybody got their flavor. And that’s ok.
But what are you going to do when all those flavors try to mix up in a team of developers with strong opinions about state management?
Some will say that using a state management library is way too complex, others will say that’s the way to go, using all the tools in the arsenal and using observable services is just not enough. As the old saying goes, the truth is somewhere in the middle.
What I want today is to explore together with you two of the most popular ways that you can do state management in Angular.
What is state management anyway?
In the frontend world, state management refers to how you organize and maintain data that reflects the current state of the application. This can mean user authentication, a list of groceries, or toggles that open or close. Anything relevant to user experience can fit here.
Using a form of state management comes with some benefits:
All the above benefits come because using state management centralizes the data in a well-defined manner and has uniform access and ways of propagating data changes.
That comes in handy when you’re building applications that need to scale. When you scale up, it’s hard to keep track of all the changes so without a process, you are doomed to fail.
Let’s take a look over two forms of state management in Angular and have a comparison between them.
Observable services
Probably one of the easiest-to-grasp method to implement state management are Observable services.
Observable services use RxJS Observables behind the scenes to manage the state reactively and asynchronously.
Using observables for me is already a great plus as they act as data streams.
A simple example would be like this:
Once you create a service, you can change the data by using the methods that you create (in our case setData()) and access data through the observable data$.
Using it in a component would be like this:
Or, a better approach, would be to use the async pipe inside the template.
<div>{{ dataService.data$ | async }}</div>
This way, you will not have to worry about unsubscribing because the async pipe will do it for you.
Depending on the method you’re using for injecting the service in the components, you can use it as a singleton service. This way, you ensure that you have only one service and only one source of truth for your data.
Every time you update the data through the methods of the service, all of the places that are subscribed to data$ will be notified and change their value.
It’s simple, it does the trick. But does it scale?
It depends on how your team is using it. If the application is small to medium, probably you won’t see the difference because the logic wouldn’t be that big.
The problem that I’ve seen in practice is that people will move the logic of the component under the service. And when I say move it, I mean like shoving the dirt under the rug.
The service will become big, and very hard to maintain. And what are you going to do with the side effects? You can either put it in the component or the service. Too many dependencies for my taste.
The worst thing you can do is to split the logic in two. You either add the side effect in the component or the service. No matter which one you will do, keep it consistent.
But what if I tell you there’s a way to enforce this kind of consistency?
领英推荐
State management – NgRx
In complex applications, you need processes to keep the code consistent. Some libraries around state management try to solve this issue by adding more layers of abstraction. Their objective is to enforce a way of manipulating data and improving extensibility.
NgRx is the subject today.
A heavy Redux-inspired library, NgRx is a library that manages state, taking into account many of the OOTB features that Angular provides.
In Observable Services, the relationship is simple. The component subscribes to the observable in the service and that’s it.
In NgRx, there is a whole process with its terminology and you have the following:
A lot, to be honest. The first time I saw this it felt overwhelming because I didn’t understand what problem it was trying to solve.
The problem that I had was just displaying a list of cars. Why wasn’t it enough to just call the service and that’s it?
One thing that I like is having a uniform way of changing the state. You do that by emitting actions. This way, you can easily reproduce the state and follow the series of events for debugging purposes.
Modern problems? Modern solutions
I had several problems that I found some answers to:
And what do I choose?
State management or Observable services? It depends on your needs. If you have a simple application that doesn’t require too much state management and logic, stick to Observable Pattern. It will solve most of your problems and you also keep it simple.
If your app is complex, the state is intertwined and you need to enforce a process, go with NgRx. It’s going to give you some complexity to your application but sticking to your process will allow you to avoid the pains of scaling.
Let’s wrap this up with a comparison table.
Using NgRX can be a great tool to add to your knowledge arsenal. Not only will you probably encounter it in big applications, but also you will learn about Redux, a pattern that is used not only in Angular but in other frameworks as well. Transferable knowledge always comes in handy.
As always, see you around,
abac team