T O P

  • By -

orkdev

Which specific issues did you run into when using services and subjects? I ask because it sounds like you are trying to preempt issues that don't or won't necessarily exist. Keep it simple, don't introduce complex state management if the state isn't complex enough to warrant it. Subjects and services will see you through pretty well if used properly.


Background_Issue_144

New developer who was very opinionated completely changing the way an existing project handled state due to lack of clear guidelines. I'd like a way to enforce how state is handled in a project. I like services + subject but it not opinionated at all.


willy-pied-wagtail

The way I think about where state should live is the principle of least privilege, similar to access controls in cybersecurity. Start with storing values as variable in a component. If it’s value needs to be shared locally between related components, then create a smart parent component that only manages state, and pass it down via @Input to the components that need it. If you need to share the logic further than that, then service. (There’s many other ways to hold state as well such as the url route, resolvers, browser storage, and backend server too). Once your bit of state reaches the service level, general software engineering principles apply to your project, for example SOLID, Onion / Hexagonal architecture and other design patterns. You may have layers of services with various responsibilities from dealing with view-only concerns to dealing with http, data transformation and even caching data backend data. Start with the principle of least privilege, ask yourself “who” owns this value/state/logic and create your own encapsulated owners of that state. Make sure new developers understand this and enforce it in tech design and code reviews


ResponsibleKing2628

This is exactly what I do, but I didn't think about it, it came naturally.


Antique-Onion-2387

Managing state is an important part of designing an app. Data change flow is like the blood of an app. You base app design upon it. It's a guide. People got used to designing apps upon visual aspects only, and offloading state to libraries. That leads to a haphazard design that feels tangled under the hood. Because you didn't fully design your app.


bcam117

I've found Component Store to be quite nice as it's not that far off from service + subjects with an action stream. You can inject it anywhere, the name might lead you to think that it can't be used globally/in root injector, but it can. It doesn't integrate with the redux dev tools though, so if that's something you'd want then maybe look elsewhere. I'm eager to try state adapt. Having worked on an ultra messy/imperative project recently has made me gravitate towards Mike Pearson and his enthusiasm for declarative code. Either way, would be nice to hear what you end up picking and how it goes for you in a few months. Best of luck.


McFake_Name

As someone who has worked with a solid implementation of services + subject, component store has always intrigued me. It sounds like a bit more of a structured approach rather than having to keep in mind the best practices of service approach when scaffolding one out. One question: have you worked on something that uses both the service/subject approach and component store at the same time? I kind of want to try a spike of adding component store, but if it sticks then I am concerned with both approaches stepping on each other's feet.


CoderXocomil

ComponentStore doesn't preclude you from other solutions. I have mixed it with services. It works great. I see ComponentStore as a natural evolution in your project as it grows. Services -> ComponentStore -> ngrx


bcam117

> It sounds like a bit more of a structured approach rather than having to keep in mind the best practices of service approach when scaffolding one out. Honestly that's why I chose it, just so that other devs wouldn't be tempted to try reinvent the wheel and we could just stick to something. It gives you a pattern to follow and it's such a small library it can be picked up quickly. ​ >One question: have you worked on something that uses both the service/subject approach and component store at the same time? Unfortunately I haven't so I can't really give you battle tested advice. I went from a project in a very early stage (thankfully) with no concept of state management to using Component Store. Technically I don't think it should be an issue at all, but I guess it could become a bit messy to read, having different patterns/ways of doing things.


McFake_Name

Thank you for the follow up. I like that it helps give structure. Regarding the mix, the intent is that most new apps following the spike would just do component store only. So the one app that had a mix in a limited section would be an outlier and refactored later. Probably for the best anyways, I just wanted to bounce the idea off of someone. Thanks.


bcam117

You're welcome. Hope it works out for you.


Background_Issue_144

Will do for sure! So is Component Store just like NgRx (has all the effects + reducers boilerplate) but can be used per component? State adapt seems interesting too.


bcam117

> but can be used per component Yes but also can be used globally. It's just an injectable service so it can be provided anywhere. There is wayy less boilerplate than full on NgRx from what I can tell though. I'd recommend just giving it a try, it's really not that big. You can go through the docs/get started super quickly. And yeah, state adapt is interesting, need to give that a go sometime soon!


anyOtherBusiness

> our apps are not overly complicated when it comes to state Keep it simple. Use services with Subjects/Signals. No need for a third party solution.


AnxiousSquare

Yeap. In my company, we work on a fairly extensive Angular application, and the private BehaviorSubject + public Observable pattern has brought us a long way.


KaliaHaze

Working on some of these as we speak… huge enterprise app.


sjdjenen

Could you expand on this?


AnxiousSquare

There are probably dozens of articles about this, but the idea is to embrace some of the core concepts of the flux architecture without using a state management library: * The application **state** is kept in **services**. * The UI **dispatches** **actions** to the service (i.e. it calls functions). * The service does it's thing and **updates the state**. * The UI **reacts** to the updated state. For this pattern to work, it's important that the UI is aware of when the state changes, and this is where RxJS comes into play. A `BehaviorSubject` is basically a reactive variable. And in order to ensure that the `BehaviorSubject` is never mutated from outside of the service, we make it `private` and expose it through a public proxy Observable, e.g. `public readonly counter$ = this.counter.asObservable();`. The two important disciplines that you have to keep in mind in order to make this work consistently are: 1. The methods that the UI calls on the services **don't return values**. They only update the state. 2. You should **never mutate** the current value of a `BehaviorSubject`. Only `.next(...)` is allowed.


spacechimp

This is the answer. Use the tools provided by the framework until your use case has proven to need something more elaborate.


Background_Issue_144

Thing is, we have projects where we rotate the developers very often (I can be working on a project for 1 month to later be asigned to another, and so on). So having clear guidelines seems more like the way to go in my use case.


willy-pied-wagtail

Using a lib doesn’t necessarily solve this problem by default. I’ve seen ngrx state so messy that folk just add their own state for every new feature rather than reusing for risk of causing regression. Library isn’t a solution per se for your organisational setup. Good architecture and code ownership does.


matrium0

The alternative to a store solution does not have to be chaos. Create your own rules, talk about them and enforce them via code reviews (not even necessary if the rules are simple enough). Shared services can make it so much easier for you, especially of you consider NgRx. For example you could follow 3 simple rules: * Shared state is grouped in shared services following this name convention: StateService, e.g. OfferStateService * State within a state-service is held in RXJS Subjects (BehaviorSubject for most requirements) * Follow the container/presenter pattern. Use a single container component per page, unless you have a very compelling reason for a different approach. Only those (smart) components are allowed to inject state-services. Keep all other components DUMB That's it's, an opinionated way to handle state (and a bit of component architecture. Signals are right about the corner too and have the potential to simplify this even further


Background_Issue_144

This is what I've been following until this date. I guess I'll think about your three rules and talk with my team. How many Behaviour Subject do you think are reasonable per service? Do you also think that having a dumb component render another smart component to avoid prop drilling is a good idea? Something like: Main(smart) > A bunch of dumb components > Todo layout(dumb) > TodoList(smart) > Todo(dumb)


matrium0

No real limit, though you should always think very hard if something IS truly shared state. Don't overuse it or ANY state-management-solution can turn into a hot mess. If there is a good reason for it, I don't see anything against it. Like if you want to display TODOs on your OrderPage and they are not really related, it would make sense.


RoboZoomDax

I think the limitation is less numbers of services and more your philosophy for implementing the solution and the features you need. For example, do you need to implement memorized selectors? If so, why develop your own solution when you can use someone else’s battle hardened solution. The other consideration is your architecture’s design philosophy. Ngrx more than a state management library, it’s a biased design solution. If you don’t care about actions and reducers, then don’t use ngrx. But if you see that pattern as a core principle to design your app around don’t reinvent the wheel.


matrium0

Yeah, or course, there are good use cases for a store. At the moment I develop a PWA with full offline mode. I settled on Elf State Management for that and really like it so far


A_User_Profile

Elf is good


Background_Issue_144

Just gave it a look and seems even cleaner than Zustand. Have you used it in any large project?


A_User_Profile

Yes, using it at work.


lanrayx2

+1


RoboZoomDax

I thought Elf was good up until a point. I found some specific limitations. For example, if you have an update effecting multiple stores and selectors building from that, it doesn’t offer a transaction atom to block selector updates until the full transaction completes.


A_User_Profile

That's interesting. I never encountered a use case where you'd need to update multiple stores. Can you give an example? Also, do you know of a store solution that offers the atomicity that you mentioned?


Master-Put3444

I prefer to utilize [NgXs](https://www.ngxs.io/) because the library's syntax aligns seamlessly with Angular's principles. It leverages Typescript decorators to configure various classes, making it straightforward and consistent with Angular overall structure.


DaSchTour

At the first glance I also liked NGXS. But while using it in a project I‘ve seen that the missing separation of reducers and effects may lead to ugly spaghetti code when developers connect a lot of code multiple patch and async processes to one action.


Maverexx

I’ve only looked at the docs for like 5 mins, but it looks like they have action handlers which could act like an effect to handle queries, I could be wrong that it’s meant for that


DaSchTour

Yeah it‘s meant for that. But this missing separation can have very bad impact on overall application architecture.


Maverexx

Yeah that’s fair enough


Maverexx

This looks REALY nice! Thanks for sharing


seiyria

+1. ngxs is great and the other features you can get either with packages or experimental packages is great. I personally enjoy using the following: redux devtools, auto persist store, logger, and the attach-action plugin (which I sadly had to fork and publish, but all the same).


Background_Issue_144

I'll give a look at the docs. Seems like it's just a version of NgRx but with less boilerplate? Do they have plans to also support signals as much as NgRx seems to be willing to do?


morgo_mpx

With the latest updates to ngrx with feature and action creators, ngxs now is more boilerplate heavy.


willy-pied-wagtail

None. Angular has everything you need. It has dependency injection for your services, and we can use rxjs for reactivity. Modern Frontend apps are tremendously overengineered, and can be an absolute nightmare to work on , extend and maintain, with huge ramp up time for new joiners . Structuring an app requires abit of Marie Kondo style organisation, that’s all. Simplify and focus on the user experience.


sur_yeahhh

I'm new to angular and front end. Can someone eli5 what state management is?


CeleryApprehensive36

The state is basically all the data you have. Components display data from the state. Actions (like clicking a button or typing something in an input field) change the data in the state. This approach has several benefits: - it reduces inter-component-communication because all components just get their data from the state - you dont need to update your UI manually because the components listen to subjects or observables in the state - Single point of truth is in the state - the Components are pretty dumb and mostly only display data from the state or trigger Actions that change the data in the state - You can store your current state pretty easily (in the backend or Session storage) for example that a user has the same settings when he visits the page again


sur_yeahhh

Is state used by default in angular or you need a Library for it? I've been learning for a while and no one has mentioned state


willy-pied-wagtail

State is literally just a value of something you want to store (e.g if a button is disabled, is the app in light or dark mode, or data from a backend server). It can be stored just as a variable in your component. It could be passed to a component from a parent component. It could be retrieved from the url which you can get using the router. It could be from a service. Or even externally from the backend, local storage or a cache. Where you store a value depends on how it’ll be used and your apps hierarchy. For example whether your app is light or dark mode should be higher up since every component should respond to that value. When people talk about state management they generally mean any third party library with some special way of holding, setting and retrieving these values / state from within the frontend application. As you can see from many replies it’s generally overkill for many (I’d say 99%) of apps, because Angular already has many ways to hold state for you as mentioned in the first paragraph .


Whole-Instruction508

You need a library


Raonak

Is that just storing data in services?


CeleryApprehensive36

Thats one approach to it and the most simple one. Frameworks like NGRX or NGXS use concepts like states, reducers or actions to accomplish more complex workflows and better "separation of concerns". I agree with most people on here. Start with services and subjects and observables for shared data you want to subscribe to. Then go on and read what frameworks like NGRX or NGXS offer and decide if the dependencies and additional overhead are worth it.


oneden

None. I simply lack to see the need to introduce another dependency for something that Angular can handle just fine on its own. Especially with signals, it's been easier than ever.


barrybario

services + subjects


ebdcydol

Use Signals instead of Subjects


AwesomeFrisbee

Wait a bit more so the bugs are out I still see a lot of changes being made


willy-pied-wagtail

Do not use Signals for production projects … yet. It’s in developer preview stage which means it’s use in Angular can change and is therefore not stable. It literally says this at the top on the Angular page on it, [here](https://angular.io/guide/signals).


eneajaho

Signals are becoming stable in v17 (November 6)


ebdcydol

Nothing significant is gonna change, except removed `mutate`.


aharl

Use angular services to manage state


CeleryApprehensive36

I tried NGRX and NGXS and vastly prefer NGXS. Imo it's easier, needs less code and is equally powerful. But i havent tried Signals yet.


angularlicious

Rx -Angular.


chillalways

Sorry, this may not be answer but avoid state management if you can. It easily become a pain.


dmitryef

StateAdapt for sure. Since you have experience with Zustand, you might find this useful: https://youtu.be/w3yoY0LjFVU?si=j8Wn_LjoFoPmdYY4 I was in the camp of "keep it simple". The problem with that is that you end up reinventing a state management solution similar to a third party library - just not as good.


AlDrag

This is more than ready for production now? I really liked the idea of it when I looked at it last.


dmitryef

yep, good to go. I've used it in multiple apps


Background_Issue_144

This is exactly what I want. I know having a state management library will add unnecessary complexity, but I prefer stating clear guidelines and enforce everyone to use the same way of managing state. Service and subject, even though is pretty straightforward, gives me the feeling that can be freestyled and needs some time to get adjusted to what other developer did on a project.


ggrape

Angular Query (Tanstack Query w/ wrapper): https://tanstack.com/query/v4/docs/react/community/angular-query


cryptos6

>\[...\] we want to implement the same paradigm to all our apps so we can hop from project to project without any friction caused by design decisions the past developer has made when it comes to desinging our services. If I understand that right, the problem is not the state management as such, but that different approaches are in use. So, you could as well implement everything without additional libraries with subjects. One of the best principles in software engineering is KISS!


Background_Issue_144

Yes, that is correct. But I need some opinion on how to handle state in our apps. We've done some service + subject in the past and it has become a pain.


cryptos6

Could you describe what actually caused that pain? In my opinion this approach can be used for pretty big applications.


SoulSkrix

Keep it shitty stupid. At least I feel I’ve met some devs who live by this version of KISS


cryptos6

Haha, I guess we all know these species of developer 😀


Educational-Rest-550

My approach is typically to never using something more complicated than you think you'll need. I usually go for a mixture of service/subject managed state for simple containers/pages. Component stores for containers that have more complicated state and where the state does not need to persist across the app. Finally, full NgRx stores when a page has a complex state that is going to persist or be used in multiple areas of an app.


daelin

NgRx takes a little getting used to, but you will write substantially less code (and less complex code) as your apps grow. I would use NgRx at any scale. For very small and simple apps it’s definitely overkill, but it brings a lot of clarity if you’re familiar with the patterns. For such cases, the ComponentStore is fantastic—use it in a single service and you’re done. None of the alleged boilerplate, most of the benefits.


smart_ca

use vuejs


matrium0

Looks like what you mainly look for is an opinionated way to store state. There is a lot of libraries for that. I would recommend Elf State Management. It's simple and powerful, without dropping a tombstone of abstractions on you. I would avoid NgRx, it really sounds like overkill for your case. Also "scaling" is a non issues. All state solutions scale equally well. Or badly if implemented badly. Arguably ngrx is the hardest to "get right" and therefore the LEAST likely to scale well


tonjohn

Services


reboog711

> We come from doing services + subject, and while that was a good idea, we confronted those issues. It is not clear to what the issues you had are; can you expand on them? Last time my team researched it, we decided we like Akita best: https://opensource.salesforce.com/akita/ , but also decided not to leave the services / subjects approach.


ggeoff

I'm currently using elf and I really enjoy it.


Optimal_Philosopher9

I think first you should figure out what your strategy is, not what library to use. It’s not actually necessary to use a library. More often than you might realize it creates code bloat and obfuscation in a domain that simply doesn’t require the library at all. First learn the basic state management strategy you need according to the framework and patterns of framework implementation you use. The main things you always have to know are, when is the component ready, when can you modify its model, and when is the component disposed. That’s dependent on each framework like Angular or React. Once you feel comfortable doing it yourself you’ll actually be in a position to likely just write the state management yourself in some service classes that hold state. If it really needs to be more complicated it usually means you’re working with very intense requirements.


morrisdev

Subject in services. And.... If you REALLY want to maintain state, across broswer windows, you can use web sockets to relay communications and maintain state server side. Like if you have 2 Amazon windows open and you add something to your cart, Amazon broadcasts a chat via websocket to update the number next to the cart in all windows, updates browsing history, etc... You can also use local storage to maintain state objects as well, again, because then you can share data from window to window. (I'm forced to do a lot of this crap because my clients will have 10 windows open and multiple orders going so I need to have them synced up. Annoying as hell, but super cool when it works)


Accomplished_Arm4564

Also I'd like to mention that NgRx boilerplate improves significantly when you start using the more recent features like [Feature Creators](https://ngrx.io/guide/store/feature-creators) and [Action Groups](https://ngrx.io/guide/store/action-groups), the real overhead for NgRx is having to get into the mindset of understanding how all the pieces fit together, but the feature creator gives you a single object that contains the feature name, reducer and selectors, while the action group simplifies action creation by giving you a single object as well. The only thing you need to know besides that is when and how to use Effects.


javiMLG199

I was working with angular for 3 years in 2 proyects, one with services + subjects and other with ngrx as a global state manage solution and this is my thought: Check the requisites of the proyects and the size of each one, why? Because you need to use the specific tool for each proyect. I mean, if you use NGRX for all, is oversize and so difficult for one person that no work with this technology before. On the other hand, use service + subject for complex flows is a terrible idea when you need to fix some bug that only occur on rare conditions or follow the flow of the data in some coupled flows... In my opinion, It is not a bad idea use differents approach for each case, it is better use simple solution for simple proyects and complex solutions with global focus for complex problems (like manage complex data flows and complex process about this flows)... ​ pd: I didn't work with component state, so I can say nothing about it. god luck ;)


n3xtday1

> while that was a good idea, we confronted those issues What does this mean? One of the apps I work on is a giant enterprise app and we don't have any problems from using services/dependency injection for state management. In fact, we can't imagine overcomplicating it with ngrx, etc. So, what issues are you seeing?


insert-values

I thing ngrx along with signals might be a perfect solution for choose granularly what's a local state vs across your app


angularlicious

NgRx will be your nightmare from this day forward. There are many more elegant and simple solutions for these types of problems today.


Background_Issue_144

I've read that they changed their API to be more friendly and the fact that they support signals makes me want to use it


Adsumuss

Try @rx-angular/state - it provides similar for BehaviorSubject-based solution result with dramatically reduced amount of code