2
votes

I have a problem with my code and distinctUntilChanged operator.

This is my code:

ngAfterViewInit() {
    fromEvent(this.headlineInput.nativeElement, 'blur').pipe(
      takeUntil(this.unsubscribe$),
      map((evt: any) => evt.target.value),
      distinctUntilChanged()
    ).subscribe((text: string) => {
      this.onInputValueChanges(text);
    });
  }

In this code, I would like to run this.onInputValueChanges(text) method on blur, but only once something has changed in headline input. If not, it should not run this method in subscribe. I thought I can use distinctUntilChanged, but it seems to not working. It runs anytime I make a blur from my headline input. Am I doing something wrong? Can someone point me out what is wrong in this code? Thanks!

1
Not sure, but maybe it's because the objects are completely different? Try to specify the comparison with distinctUntilChanged((prev, curr) => prev.something === curr.something). - brandt.codes
Hi, thanks for the answer. I also thought about this solution, but I'm not sure what exactly here should be compared. - ciolas2
hmm... I would just print (console.log) the object (prev) to check what is inside. And afterwards decide what to compare. - brandt.codes
Hi ciolas2, actually your approach works, You should use distinctUntilChanged here. Look at my stackblitz: stackblitz.com/edit/angular-ivy-5urdzg?file=src/app/… (it renders the result in console). Play around with tab button a little bit. So, I think, the problem is with the headline input. Could you provide more details? - greatromul
Yes, it seems that something is wrong with my input. My Input value on start is passed as @Input() inputValue: string; My method works, but only once I ran it second time, it's not working on first time, because my inputValue is undefined on ngAfterViewInit. On my second blur it's working properly. At your stackblitz, you added value="John Doe" I think that's why it works in your case because it has something to compare - ciolas2

1 Answers

3
votes

If you want to be lazy, you can just check the object value being different than the previous emission.

ngAfterViewInit() {
    fromEvent(this.headlineInput.nativeElement, 'blur').pipe(
      takeUntil(this.unsubscribe$),
      map((evt: any) => evt.target.value),
      // don't run if the stringified version of the object is the same.
      distinctUntilChanged((pre: any, curr: any) => JSON.stringify(pre) === JSON.stringify(curr)),
    ).subscribe((text: string) => {
      this.onInputValueChanges(text);
    });
  }