Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rxjs `distinctUntilChanged()` appears to not be working

In an rxjs stream, I'm using distinctUntilChanged with lodash's isEqual to filter out duplicate values. However it appears to not be working as expected. Take the following code snippet

import { isEqual } from 'lodash-es';

let cachedValue: any;

function testFn(observableVal: Observable<any>) {
  return observableVal
    .pipe(
      distinctUntilChanged(isEqual),
      tap(val => {
        const equal = isEqual(cachedValue, val);
        console.log('"output":', equal, cachedValue, val);
        cachedValue = val;
      })
    )
}

In this example, I would expect that const equal inside the tap function would never === true. I would expect that distinctUntilChanged(isEqual) would filter out any values where isEqual(cachedValue, val) === true --> meaning that const equal === false always. However, console output shows:

"output": false undefined [ContactList]
"output": true [ContactList] [ContactList]
"output": true [ContactList] [ContactList]
"output": true [ContactList] [ContactList]

Do I misunderstand something fundamental about how the distinctUntilChanged() operator works? I've posted a simplified example because the actual rxjs stream is very complex, but I wouldn't expect the complexity to make any difference in so far as const equal should always === false in the tap operator.

I'm just trying to understand what's going on, so any info is appreciated. Thanks!

Update

It should be noted that if I change the code to:

function testFn(observableVal: Observable<any>) {
  return observableVal
    .pipe(
      filter(val => {
        const equal = isEqual(cachedValue, val);
        cachedValue = val;
        return !equal;
      }),
      tap(val => {
        console.log('"output":', val);
      })
    )
}

Then the filtering works as expected. I was under the impression that distinctUntilChanged(isEqual) was equivalent to:

filter(val => {
  const equal = isEqual(cachedValue, val);
  cachedValue = val;
  return !equal;
})

Am I mistaken / misunderstanding the distinctUntilChanged operator?

like image 876
John Avatar asked Feb 24 '19 21:02

John


1 Answers

I figured it out! Thanks to a comment in an rxjs issue: I had accidently subscribed to the observable multiple times (which shouldn't have happened). The multiple console.log instances were coming from different subscription instances.

like image 120
John Avatar answered Nov 03 '22 02:11

John