3

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!

6
  • 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). Commented Oct 30, 2020 at 15:49
  • Hi, thanks for the answer. I also thought about this solution, but I'm not sure what exactly here should be compared. Commented Oct 30, 2020 at 15:50
  • hmm... I would just print (console.log) the object (prev) to check what is inside. And afterwards decide what to compare. Commented Oct 30, 2020 at 15:57
  • 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? Commented Oct 30, 2020 at 16:05
  • 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 Commented Oct 30, 2020 at 16:16

1 Answer 1

4

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);
    });
  }
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.