Integrating NGRX Signal Store with an existing Angular application

Over the years, your application have grown huge. Sometimes, really HUGE.

Many developers have contributed to the codebase. One day they pushed one coding style, a different one another day. Sometimes even different patterns and solutions for similar problems.

You want to keep your codebase consistent. In the Angular ecosystem, there were well established patterns for doing things the right way ™️. But the old solutions are being challenged by signal-based approach.

Eventually, you ask yourself the key question: Should you integrate with the NEW solutions or stick to the battle-tested ones, but already considered LEGACY?

That's a very good question indeed. Don't rush with architectural decisions 🤓.

First, think of what problems you want to solve by introducing the change.

Do you have 1k LoC Angular components? Maybe even 2k? Do you and your team enjoy working with these? 😏

Where does the domain logic and state management code belong to - do you have a clear guidance on which code should be put where? Have you spot that different devs implement similar features in totally different ways?

Do you keep on asking the same questions over and over again: whether this certain piece of code should be imperative (plain old object properties and variables) or reactive (streams)? It'd be nice to keep all thinga reactive, but more often than not, it introduces complexity.

Second, think of long-term consequences.

You are going to have more than one way to manage the state. But is that really an issue? If your codebase is modular, separate modules should not depend on each other in any way. Inner abstractions of one should be invisible to the other, etc.

You are going to introduce a new tool. On one hand, you need to learn it, and so does your team. But on the other hand, it's a breathe of fresh air. And it's useful to question the way you've been doing things so far. Maybe there's a more effective way?

You are going to embrace signal-based APIs. And that means taking taking advantage of Zoneless Angular. This means using all modern Angular APIs. And you know that signals are the future. Why would you want to stick to the less performant, less type-safe, less flexible and, objectively, less effective solutions?

Finally, plan your INCREMENTAL integration.

INCREMENTAL is the absolute keyword here. You don't want to tell your PM you need to stop delivering features because of a refactor.

Actually, there's no need for a "refactor". Just pick the first new feature to be implemented. Or pick the one that needs to be extended.

NGRX Signal Store allows you to create both very simple & small stores, as well as bigger ones. Composition is the key here.

Start simple.

Create a withState section with the signals that hold the state. That's already reactive. And relatively simple.

const initialState: CartState = { items: ..., rebate: ..., } export const CartStore = signalStore( withState(initialState) );

Create a withMethods section to provide ways to change the state:

export const CartStore = signalStore( ... withMethods((store) => ({ addItem(item: ShoppingItem): void { patchState(store, (state) => ({ items: [ ...state.items, item ] })); }, ... );

Create a withComputed section to provide all derived computations:

export const CartStore = signalStore( ... withComputed(({ items }) => ({ totalPrice: computed(() => items().reduce(...)) ... );

Start simple.

Now you can (literally) inject this code into your existing solution. All you need is to inject your brand new NGRX Signal Store implementation into a component, or a service:

@Injectable() class ExistingBigService { cartStore = inject(CartStore) //... }

and that's it! What's beatiful is that NGRX Signal Store should remain an implementation details (of a component, service, etc). It shouldn't leak outside to the entire application unintentionally. Small NGRX Signal Stores help us to keep logic more modular.

Don't hesitate - give NGRX Signal Store a try! Start with the Scalable Signals Angular Architecture with NGRX Signal Store course now!

Share with a coworker