0
0
AngularHow-ToBeginner · 3 min read

How to Use distinctUntilChanged in RxJS for Angular

Use the distinctUntilChanged operator in RxJS to ignore consecutive duplicate values emitted by an observable. It helps prevent unnecessary updates by only passing values that differ from the previous one.
📐

Syntax

The distinctUntilChanged operator is used as a pipeable operator in RxJS. It can be used with or without a comparison function.

  • distinctUntilChanged(): Uses strict equality (===) to compare values.
  • distinctUntilChanged(compareFunction): Uses a custom function to compare previous and current values.
typescript
import { distinctUntilChanged } from 'rxjs/operators';

observable.pipe(
  distinctUntilChanged(),
  // or with a custom compare function
  distinctUntilChanged((prev, curr) => prev.id === curr.id)
)
💻

Example

This example shows an observable emitting numbers with some duplicates. Using distinctUntilChanged filters out consecutive repeated numbers, so only changes are logged.

typescript
import { of } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

const numbers$ = of(1, 1, 2, 2, 2, 3, 1, 1);

numbers$
  .pipe(distinctUntilChanged())
  .subscribe(value => console.log(value));
Output
1 2 3 1
⚠️

Common Pitfalls

One common mistake is expecting distinctUntilChanged to filter out all duplicates, but it only removes consecutive duplicates. Non-consecutive duplicates will still pass through.

Another pitfall is not providing a proper comparison function when working with objects, which leads to unexpected behavior because objects are compared by reference.

typescript
import { of } from 'rxjs';
import { distinctUntilChanged } from 'rxjs/operators';

const objs$ = of(
  { id: 1 },
  { id: 1 },
  { id: 2 },
  { id: 2 },
  { id: 1 }
);

// Wrong: no custom compare, compares object references
objs$
  .pipe(distinctUntilChanged())
  .subscribe(console.log);

// Right: compare by id property
objs$
  .pipe(distinctUntilChanged((prev, curr) => prev.id === curr.id))
  .subscribe(console.log);
Output
{ id: 1 } { id: 1 } { id: 2 } { id: 2 } { id: 1 } { id: 1 } { id: 2 } { id: 1 }
📊

Quick Reference

  • distinctUntilChanged(): Filters out consecutive duplicate primitive values.
  • distinctUntilChanged(compareFn): Use for custom comparison, especially with objects.
  • Only consecutive duplicates are filtered, non-consecutive duplicates pass through.
  • Useful to reduce unnecessary UI updates or network calls.

Key Takeaways

distinctUntilChanged filters out only consecutive duplicate values from an observable.
Use a custom compare function with distinctUntilChanged when working with objects.
It helps optimize performance by preventing unnecessary repeated emissions.
Without a compare function, it uses strict equality (===) for comparison.
Non-consecutive duplicates are not filtered by distinctUntilChanged.