Aurelia Store is a powerful state management library for your Aurelia applications, but behind-the-scenes it merely wraps the powerful RxJS observable library. This means you can use a plethora of RxJS methods to change how Aurelia Store works.
Problem: Aurelia Store will fire all state subscribers regardless of change
Whenever your state changes, all listeners of the state object will be fired. While smaller applications won’t introduce any noticeable differences, as your application grows in size and complexity, depending on what you’re doing inside of those store subscribers you can run into some issues.
Sometimes you only want code to run inside of an Aurelia Store subscription if it needs too, akin to some kind of if statement that checks if the code needs to be run.
For example, if you have a isLoading
property in your store that changes depending on whether or not something is loading, any code that watches this property should only fire when it changes, not whenever the store’s state changes. Why should isLoading
checks care if you’ve loaded a bunch of users or products data?
Solution
Using the RxJS methods pluck and distinctUntilChanged, we can tell our subscriptions to only fire if a specific property in our store has changed. The pluck
method allows us to tell RxJS to only watch a specific property in our state object. For the above loading example, we would want to “pluck” the isLoading
property pluck('isLoading')
.
Lastly, we want to use the distinctUntilChanged
method which accepts no arguments. All it does is takes our “plucked” value and compares it to its previous value to see if it changed or not.
import { distinctUntilChanged, pluck } from 'rxjs/operators'; this.store.state.pipe(pluck('isLoading'), distinctUntilChanged()).subscribe((isLoading) => { // The isLoading property changed });
Now, this works great for most use cases. However, as documented in the distinctUntilChanged
the documentation details a caveat on how the check works you need to be aware of.
distinctUntilChanged uses
===
comparison by default, object references must match!
If you want to do a check based on an object property, you need to use the distinctUntilKeyChanged method which is not covered in this post.
Really, that is all there is to it. You pluck a property and then you do a distinct check to react whether or not the value has changed. This is all just RxJS code and nothing overly Aurelia Store specific. There are a tonne of other RxJS operators you should read up on.