autoboxer
autoboxer

Reputation: 1397

Using Observable data from one ngrx store reducer to filter results in another

my ngrx store consists of two sets of data: preferenceGroups which hold groups of selected preference values and stocks:

there are a lot of preferenceGroups, in one of two formats, a group of boolean values or a range:

"preferenceGroups": [
    {
        "name": "Sectors",
        "type": "toggles",
        "preferences": [
            {
                "label": "Sector 1",
                "type": "boolean",
                "value": true
            },
            {
                "label": "Sector 2",
                "type": "boolean",
                "value": true
            }
        ]
    },
    {
        "name": "Exchange",
        "type": "toggles",
        "preferences": [
            {
                "label": "Exchange 1",
                "type": "boolean",
                "value": true
            },
            {
                "label": "Exchange 2",
                "type": "boolean",
                "value": true
            }
        ]
    },
    {
        "name": "Price",
        "type": "price-range",
        "preferences": {
            "label": "Price",
            "type": "currency",
            "value": {
                "minimum": 0,
                "maximum": 999
            }
        }
    },
    ...
]

I also have a bunch of stocks, all with the same fields, generally they look like this:

"stocks": [
    {
        "state": {
            "accepted": false,
            "rejected": false
        },
        "change": -5.36,
        "changePercent": -0.13,
        "dividend": 12.05,
        "equitySummaryScore": 8,
        "exchange": "Exchange 1",
        "price": 97.10,
        "sector": "Sector 1",
        ...
    },
    ...
]

The way my filters work is for each preferenceGroup, I'd like to consider any stock that has a value matching any of the boolean filters set to true, and in the case of a range, any value that is within the range.

I can get all the stocks and preferenceGroups from my ngrx store as Observables using

this.stocks = this._store.select('stocks');
this.preferenceGroups = this._store.select('preferenceGroups');

what I need to do is store the filtered stocks as an Observable by using the data in this.preferenceGroups to filter this.stocks.

this.filteredStocks = [something I can't figure out]

for example, the single stock I listed would be a match because it has "exchange": "Exchange 1", "sector": "Sector 1" and "price": "97.10"

Upvotes: 3

Views: 2213

Answers (1)

KwintenP
KwintenP

Reputation: 4775

If you have two observables, one with the stocks, the other with your filter, you need to combine both streams. What you need is an array of every stock and your preferences to know if you can show them. Check the following code:

let stocks$ = Rx.Observable.of(["stock1", "stock2", "stock3"]);

let preferences$ = Rx.Observable.of(["preference", "preference2"]);

let combined$ = Rx.Observable.combineLatest(
  stocks$, preferences$, (stocks, preferences) => {
      // implement your filtering logic here and returned the filtered stocks
      return stocks + " " + preferences
  });


combined$.subscribe((val) => console.log(val));

When using combineLatest, you combine two observables. The function that is being passed to the combineLatest method will be given the latest value from the stocks$ observable and the last from the preferences$ observable. These observables are coming from your store.

In this function, you can just implement you filtering logic like you would in an imperative style.

Every time a new stock is being added to the store, ngrx will push a new value to the stock observable, and the function with your logic will be re-evaluated. The same goes for a new preference.

If you subscribe to your combined$ stream in your template, every stock add or preference add will result in an updated view.

Upvotes: 3

Related Questions