Querying a Normalized State with RxJS in Angular

Netanel Basal
Netanel Basal
Published in
3 min readMay 27, 2017

--

This post assumes that you at least have some working knowledge of ngrx/store and RxJS.

In this article, we are going to learn how we can query normalized state in our redux store.

Let’s say we have a blog and our normalized state look like this:

First let’s create our smart component.

I’m going to abstract the queries to a dedicated service for three reasons:

  1. I do not like the idea of injecting the Store into my component. The component does not need to know how he gets the data. ( For the same reason that you do not inject the HTTP service. )
  2. I want the ability to reuse my queries in any other parts of my application.
  3. I want to keep my component clean.

Now let’s create the ArticlesQuery .

First, we need to create a dedicated selector for every part of the state so that we can compose them later.

Now let’s say we have a place in the app that needs only the articles. (aside area for example)

The result and articles depend on each other ( if we add new article we need to update both the result and the articles ), so our best choice is to use the zip operator.

After all observables emit, emit values as an array

We can also use the second parameter — resultSelector. A function which takes the inputs at the specified index and combines them together.

combineLatest will also work but I prefer zip in this case.

update: combineLatest is a better option.

Now let’s say we need the articles with their comments.

Do you see where I’m going with this? We can compose queries to get the necessary data.

Now let’s say we need the articles with their comments and the authors.

Now let’s add a selectedArticle key to our state.

If we want to display the selected article we can use the withLatestFrom operator.

Also provide the last value from another observable

When the selectedArticle changes our observable emits new value with the latest articles and our component will re-render.

If we need only the article without any other data we can do this:

Angular Router

The Router params are an observable so for example, if we store the selected id in the URL we can query the article like this:

Form Control

The valueChanges property is an observable, so for example if we need to implement search we can do this like this:

Let’s say you need to get the favorite articles of a user, and this information is stored in a user reducer.

You don’t need reselect

The select() method will give you an observable that calls distinctUntilChanged() internally, meaning they will only fire when the state actually changes. ( it means when there is a new reference ).

Summary

In the end, you have to remember that everything is a stream. You can use various observables/operators to compose data from your state or any other source.

combineLatest , withLatestFrom , zip, concat , forkJoin ,merge and more…

🔥 Last but Not Least, Have you Heard of Akita?

Akita is a state management pattern that we’ve developed here in Datorama. It’s been successfully used in a big data production environment for over seven months, and we’re continually adding features to it.

Akita encourages simplicity. It saves you the hassle of creating boilerplate code and offers powerful tools with a moderate learning curve, suitable for both experienced and inexperienced developers alike.

I highly recommend checking it out.

Follow me on Medium or Twitter to read more about Angular, Vue and JS!

--

--

A FrontEnd Tech Lead, blogger, and open source maintainer. The founder of ngneat, husband and father.