Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@ngrx/store subscription to part of a store and avoid detecting changes to other parts

Tags:

angular

rxjs

ngrx

Background

One of the reducers in my store deals with things that are selected within the app. The interface for this store (let's called it app) could look like this:

interface IApp {
    selectedProject: IProject;
    selectedPart: IPart;
}

So I want to have a subscription that performs an action only when a different 'project' is selected. I wrote something like this:

this.store.select('app')
    .map((store: IApp) => store.selectedProject)
    .subscribe((project: IProject) => {
        // Stuff happens here
    });

This function does it stuff when selectedProject changes. However, it also does it stuff when selectedPart changes. Clearly, it listens to the whole of the app store, regardless of the map. That makes sense.

Question

I don't want this to happen. I only want my function to execute when selectedProject changes.

I know I can split selectedProject and selectedPart into different stores to solve this. However, I could quickly end up with many, many stores. Maybe this the way it is meant to be?

Is there another way though? Can I keep the store with this interface and have a subscription that only detects changes to the selectedProject part of the store?

like image 620
freethebees Avatar asked Jul 14 '16 09:07

freethebees


1 Answers

I believe you are looking for distinctKeyUntilChanged.

this.store.select('app')
  //Only emit when selectedProject has changed
  .distinctUntilKeyChanged(
    //Key to filter on
    'selectedProject',
    //Optional comparison function if you have a specific way of comparing keys 
    (x, y) => x.projectName === y.projectName)
  .pluck('selectedProject')
  .subscribe((project: IProject) => {});
like image 102
paulpdaniels Avatar answered Nov 08 '22 09:11

paulpdaniels