function stable operator
Returns a result Observable that emits all values pushed by the source observable if they are distinct in comparison to the last value the result observable emitted.
distinctUntilChanged(comparator?: (previous: T, current: T) => boolean): MonoTypeOperatorFunction<T> comparator | (previous: T, current: T) => boolean | Optional. Default is |
distinctUntilChanged(comparator: (previous: K, current: K) => boolean, keySelector: (value: T) => K): MonoTypeOperatorFunction<T> comparator | (previous: K, current: K) => boolean | |
keySelector | (value: T) => K |
When provided without parameters or with the first parameter (comparator), it behaves like this:
comparator or an === equality check.When the second parameter (keySelector) is provided, the behavior changes:
keySelector will be run against all values, including the first value.comparator.A very basic example with no comparator. Note that 1 is emitted more than once, because it's distinct in comparison to the previously emitted value, not in comparison to all other emitted values.
import { of, distinctUntilChanged } from 'rxjs';
of(1, 1, 1, 2, 2, 2, 1, 1, 3, 3)
.pipe(distinctUntilChanged())
.subscribe(console.log);
// Logs: 1, 2, 1, 3 With a comparator, you can do custom comparisons. Let's say you only want to emit a value when all of its components have changed:
import { of, distinctUntilChanged } from 'rxjs';
const totallyDifferentBuilds$ = of(
{ engineVersion: '1.1.0', transmissionVersion: '1.2.0' },
{ engineVersion: '1.1.0', transmissionVersion: '1.4.0' },
{ engineVersion: '1.3.0', transmissionVersion: '1.4.0' },
{ engineVersion: '1.3.0', transmissionVersion: '1.5.0' },
{ engineVersion: '2.0.0', transmissionVersion: '1.5.0' }
).pipe(
distinctUntilChanged((prev, curr) => {
return (
prev.engineVersion === curr.engineVersion ||
prev.transmissionVersion === curr.transmissionVersion
);
})
);
totallyDifferentBuilds$.subscribe(console.log);
// Logs:
// { engineVersion: '1.1.0', transmissionVersion: '1.2.0' }
// { engineVersion: '1.3.0', transmissionVersion: '1.4.0' }
// { engineVersion: '2.0.0', transmissionVersion: '1.5.0' } You can also provide a custom comparator to check that emitted changes are only in one direction. Let's say you only want to get the next record temperature:
import { of, distinctUntilChanged } from 'rxjs';
const temps$ = of(30, 31, 20, 34, 33, 29, 35, 20);
const recordHighs$ = temps$.pipe(
distinctUntilChanged((prevHigh, temp) => {
// If the current temp is less than
// or the same as the previous record,
// the record hasn't changed.
return temp <= prevHigh;
})
);
recordHighs$.subscribe(console.log);
// Logs: 30, 31, 34, 35 Selecting update events only when the updatedBy field shows the account changed hands.
import { of, distinctUntilChanged } from 'rxjs';
// A stream of updates to a given account
const accountUpdates$ = of(
{ updatedBy: 'blesh', data: [] },
{ updatedBy: 'blesh', data: [] },
{ updatedBy: 'ncjamieson', data: [] },
{ updatedBy: 'ncjamieson', data: [] },
{ updatedBy: 'blesh', data: [] }
);
// We only want the events where it changed hands
const changedHands$ = accountUpdates$.pipe(
distinctUntilChanged(undefined, update => update.updatedBy)
);
changedHands$.subscribe(console.log);
// Logs:
// { updatedBy: 'blesh', data: Array[0] }
// { updatedBy: 'ncjamieson', data: Array[0] }
// { updatedBy: 'blesh', data: Array[0] }
© 2015–2022 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors.
Code licensed under an Apache-2.0 License. Documentation licensed under CC BY 4.0.
https://rxjs.dev/api/operators/distinctUntilChanged