12

For rxjs, can I provide an initial value when using distinctUntilChanged? It seems that the equals check is skipped entirely when no previous value was received. I'd like to not emit anything when the first value it receives is the initial value.


Use case

In my case I'm working with angular, I'm working with reactive forms and subscribing to its value changes. Since it's an input field I have a typical pipe setup:

  • debounceTime(350)
  • distinctUntilChanged()

When the user changes the initial field from empty to something and then empty again within the debounce time, the event is triggered anyway which should not happen.


What I've tried

  • Supply a custom equals method in distinctUntilChanged
    • Does not work since the pipe is skipped entirely when encoutered for the first time
  • Force a next on the underlying subject with the default value
    • This still emits a value after the debounce time which I'd rather avoid
Didii
  • 1,194
  • 12
  • 36
  • Instead to me seems that `distinctUntilChanged` is ignored the first subscription, despite the fact that there is a value or not – albanx Jan 20 '19 at 22:09
  • 3
    @albanx Yes, `distinctUntilChanged` can only skip an event if it knows what the previous value was. Since on its first subscription there is no prior event recorded, the first event is always different than nothing. – Didii Jan 22 '19 at 20:27

3 Answers3

12

You can try startWith:

const valueChanges$ = this.form
  .get('CONTROL_NAME')
  .valueChanges
  .pipe(
    startWith('INITIAL_VALUE'),
    distinctUntilChanged(),
    skip(1)
  )
  .subscribe((value: string) => { ... });
mtpultz
  • 17,267
  • 22
  • 122
  • 201
5

You can use skip to skip the first emit or skipWhile to skip only the initial value.

obs.pipe(
  debounceTime(350),
  distinctUntilChanged(),
  skipWhile(value => value === initialValue) // or skip(1)
) 
m1ch4ls
  • 3,317
  • 18
  • 31
  • Doesn't seem like there is a better way. The `skipWhile` you provided will however always skip the `initialValue`. – Didii Sep 05 '18 at 12:32
0

Using startWith or skipWhile operators don't do the trick, as confirmed by comments.

I solved simply using skip(1):

const valueChanges$ = this.form
  .get('CONTROL_NAME')
  .valueChanges
  .pipe(
    skip(1)
    distinctUntilChanged(),
  )
  .subscribe((value: string) => { ... });
smartmouse
  • 13,912
  • 34
  • 100
  • 166