stevenjmyu
stevenjmyu

Reputation: 946

How to use rxjs map to filter out an observable list of object by another list of objects of different type

I have an observable list that I'm returning from an api and i want to filter it base on a property value of another list that I have in local session storage. It's basically an inner join. is there a better way than using rxjs map / filter? This filter works for a single value but I'm not sure how to go about filtering it based on a property value of a list

 loadTable() {
    this.service.getSomeDataFromAPI() 
    .pipe(
      map(
        items => items.filter(item => item.branchCode.indexOf(StaticListOfObjects.branchCode) > -1)       
         )
     )
    .subscribe(response => {  ...  }
    );
  }

This is my staticListOfObject and I need to filter for all the objects that matches branchCode.

[
  {
    branchCode: "AV1",
    summaryCount: 10,
  },
  {
    branchCode: "AV2",
    summaryCount: 5,
  },
  {
    branchCode: "BR1",
    summaryCount: 4,
  },
];

Upvotes: 0

Views: 3225

Answers (2)

dmbarreiro
dmbarreiro

Reputation: 154

Considering

const StaticListOfObjects = [
  {
    branchCode: "AV1",
    summaryCount: 10,
  },
  {
    branchCode: "AV2",
    summaryCount: 5,
  },
  {
    branchCode: "BR1",
    summaryCount: 4,
  },
];

another possible solution if your observable completes after sending the first array (and you are willing to use ES6) could be

loadTable() {
    const valid_values = StaticListOfObjects.map(x => x.branchCode);
    this.service.getSomeDataFromAPI() 
      .pipe(
        concatMap(y => y),
        filter(y => valid_value.includes(y.branchCode)),
        toArray(),
      )
      .subscribe(response => {  ...  }
 }

concatMap gets your array and emits observables of all its values, then you filter on each object with the filter operator and finally toArray bundles up all those filtered into an array when the observable returned by getSomeDataFromAPI() completes (this is the reason why it only works if the observable completes after emitting the first array, if it doesn't then the pipe will keep filtering newly emitted arrays until the observable completes returning all filtered values from all received source arrays into a single result array).

Upvotes: 1

Sergey Rudenko
Sergey Rudenko

Reputation: 9227

Since API call returns a list (I presume an array) you just need to map it and filter it like so;

  let filterArray = [
  {
    branchCode: "AV1",
    summaryCount: 10
  },
  {
    branchCode: "AV2",
    summaryCount: 5
  },
  {
    branchCode: "BR1",
    summaryCount: 4
  }]

  loadTable() {
    this.service.getSomeDataFromAPI().pipe(
      map(
        items => items.filter( item => {
          if (filterArray.find(filterItem => filterItem.branchCode == item.branchCode)) {
            return true
          } else {
            return false
          }
        })   
      )
    ).subscribe(response => {  ...  });
  }

Upvotes: 1

Related Questions