nikk wong
nikk wong

Reputation: 8670

Rxjs filter a composable stream based on another stream

I have an array of cars that have properties:

cars: <Car[]> = [
    {
        color: 'red',
        make: 'mazda',
        year: 1960
    },
    {
        color: 'blue',
        make: 'mazda',
        year: 1984
    },
    {
        color: 'red',
        make: 'honda',
        year: 1999
    }
]

The observable updatesToCars is being modified and assigned to another observable carsObservable via .scan and .cache.

let initialCars = cars;
carsObservable = updatesToCars.scan(
    (cars: Car[], operation /* some crud operation that modifies the cars array */) => {
        return operation(cars);
    }, initialCars
).cache();

carsObservable now has the most up to date list of cars. Cool! Let's now say I want to filter for all the cars that are of a certain make, whilst keeping composability in mind:

carsOfACertainMake = new BehaviorSubject('mazda');
filteredCarsOfACertainMake = carsOfACertainMake.map((make) => {
    return carsObservable.map((cars) => {
        return _.filter(cars, function(car) {
            return car.make === make;
        });
    });
}).switch().cache();

Now we can carsOfACertainMake.next('honda') and the filteredCarsOfACertainMake observable will only reflect cars that have the make value of honda.

We essentially have to empty out the filteredCarsOfACertainMake observable every time the need to filter by a different make is requested.

This works, but seems like a strange way to implement such functionality. Can the .filter observable achieve this instead? And if so, what is the required code?

Thanks.

Upvotes: 0

Views: 574

Answers (1)

paulpdaniels
paulpdaniels

Reputation: 18663

I think you are looking for either combineLatest or withLatestFrom

var carsOfACertainMake = new BehaviorSubject('mazda');
carsObservable.withLatestFrom(carsOfACertainMake, (cars, make) =>
  _.filter(cars, car => car.make === make)
).cache();

filter is not going to help you very much in this situation because it can't really handle the case of a mutating criteria. Instead withLatestFrom will avoid the resubscription cost from above and will always emit with the latest filter set each time carsObservable emits.

Upvotes: 1

Related Questions