Introducing NGRX Actions 3.0
In NGRX Actions 3.0, we have some exciting new features.
- Remove the need to call
- Dependency Injection in our Stores
- Addition of Effects in our Stores
None of these changes are breaking so all the old APIs you were using still work. Lets take a minute to break down what changed and why.
No need to call createReducer anymore
createReducer method was a factory function that would change our ngrx-action classes into reducers that NGRX could handle. This made ngrx-actions super flexible and easy to add in to any ngrx project, however, because of AoT not allowing function invocations in module declarations, we had to write some verbose code to handle this. This looked like:
One of the main reasons I wrote ngrx-actions was to reduce boiler plate and well this was boilerplate. So now with ngrx-actions 3.0 you can invoke the
NgrxActionsModule with your classes directly removing the need for this. The above becomes this:
Thats much nicer. Again this is not a breaking change though, so you can still do the old way.
Dependency Injection in our Stores
Oftentimes we write services to do things like calculate permissions and we make them as services but because NGRX stores are pure functions we have no way to actually use those services in our store. In Angular, we rely on DI quite a bit so why not leverage that capability in our stores too?
Previous to 3.0, we had a
createReducer function call I mentioned above that would create our reducer factory for us. In 3.0, we enhanced this to when you passed it to the
NgrxActionsModule it would be able to resolve the class using the injector thus giving us the ability to use DI now. So lets take a look at how we do this:
In this example, we did a few things to make it DI-able. First we added
Injectable decorator to our store. Then in our module, we used our new pattern of initializing stores and also added
PizzaStore as a provider so it can resolve our app depedencies. Presto!
Effects in Stores
As I mentioned above, one of the main reasons I created ngrx-actions was to reduce boilerplate of NGRX. Having separate files for all these different pieces (actions, selectors, reducers, effects) just felt daunting. So why not merge actions and effects into one logical place?
Now, I can already hear some of you disagreeing with this change stating it blurs the separation of concerns but I disagree. In a event sourcing world, you are dispatching events and listening to those events and doing some action whether that is manipulating a state or dispatching a saga ( saga is commonly used in discussions of CQRS to refer to a piece of code that coordinates and routes messages between bounded contexts and aggregates ).
On top of logical organization of these, I felt like NGRX effects are really dense , hard to read and difficult for beginners. Your effects often have lots of redundancies that could be simplified too. Lets take a look at an effect that I have today:
This effect is pretty intense but what its doing is actually pretty simple:
- Listen for Cancel Pizza Action
- Map the payload which is the justification for canceling
- Get the pizzas in the store
- Map those to a new object which contains the justification and the pizzas from the store
- Call the service to cancel the pizzas
- Emit the cancel pizza event and show a notification
In ngrx-actions 3.0 this could be reduced quite a bit:
Isn’t that nice?!
ngrx-actions 3.0 provides some quite powerful new features. All these features are optional, non-breaking and you can use as much or as little as you like. Hope you enjoy!