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!
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?
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.