@ngrx/data Will Change Your Life
By: Jamie Morris
Tags: Ngrx, Angular, JavaScript, Programming, Redux

@ngrx/data Will Change Your Life

Remove React boilerplate and simplify your codebase

Photo by Ben White on Unsplash

I’ve been using some form of the Redux pattern for a couple of years now, and with some small exceptions, I’m largely doing the same kind of things each time — creating entities, reading them, updating them, deleting them.

CRUD applications still form the bulk of the work that I do as a front-end developer. A little voice in the back of my mind was telling me that I should have found a way to reduce the boiler plate I keep writing, but a louder voice in the front of my mind was relishing the chance to tweak my approach with each successive implementation.

I’ll be the first to admit that some of NgRx felt like overkill — I rarely use things like createSelector , and didn’t really use side-effects much either.

Most of the time, I felt like I was doing it “wrong”, but it was right enough for me. Still, I kind of hoped that next time around I might have that lightbulb moment that would lead me to do it “right”.

Then, I attended a workshop at AngularConnect 2019 run by John Papa and Ward Bell when they blew my tiny mind right out of my skull with @ngrx/data.

This is the library I’ve been waiting for, but to make sure we’re all on the same page, let’s talk about how I’d do this stuff with just @ngrx/store.

Disclaimer: I wrote the below snippets from memory without testing them —they are missing a few bits and I’d be very surprised if they actually work. They are, however, mostly right and indicative of the kind of work I’m trying to demonstrate.

Actions and Reducer for a simple customer store

The above snippets are missing some obvious pieces: they aren’t wired up to AppModule and there are no effects for persisting data.

But you can see that for a relatively simple example, there are a total of 62 lines of code. That’s not terrible, and is a small price to pay to adopt a pattern that scales incredibly well as your application grows.

But you will have to write the same 62 lines of code when you want to implement another entity-type state (e.g. products, orders, etc.).

On top of that, the effects to fetch that data from an API are another big time-sink, requiring you to consider things like signaling when the data is loading (commonly, you’ll be loading via an API where latency might be an issue).

Perhaps more importantly, this is all code you have to write tests for, since it’s code you wrote and you control. I tend to find that Redux makes writing tests easier, but there’s still a lot of effort involved if you’re going to be doing the same thing for every entity type you store.

This is where @ngrx/data comes in. The authors have identified commonalities between these kinds of data and written a library to handle it. All you need to do is provide a config. Here’s an example:

This is already down to 22 lines of code. And get this: that includes a default behavior that persists data via a RESTful API using effects. It assumes you use proper HTTP verbs to interact with your API.

For instance, if you have the following endpoints, the DefaultDataService will persist data via REST with no configuration:

/api/customer (POST)

/api/customer/:id (GET, PUT or DELETE)

/api/customers (GET)

If you don’t want any effects at all, you can easily configure your store not to use any effects. If you would rather persist data in another way, you can do so by writing your own data service.

For example, I wanted to persist entity data to local storage for a phone app I was building, so I wrote this service:

LocalStorageDataService example

Feel free to reuse it in your own work — it is incomplete but demonstrates how to wire up something other than the default behavior.