BehaviorSubject subscriber gets same next() element multiple times

10,166

Solution 1

A new subscription is added every time ngDoCheck() is called. Try using first() to only get the value once and then automatically unsubscribe.

ngDoCheck() {
    this.shareDataService.currentMessage
        .pipe(first())
        .subscribe((message) => {
            // Do stuff
        }
    });
}

The next time ngDoCheck is triggered, it adds another one-time subscription.


If your only intention of the subscription is to get the current value on change detection, you can also add a simple get() function to your ShareDataService to just return its current value.

get() {
    return this.messageSource.getValue();
}

Solution 2

Can you please try calling the unsubscribe in your ngOnDestroy() lifecycle hook

ngOnDestroy() {
    this.shareDataService.currentMessage.unsubscribe();
}

Hope this helps!

Share:
10,166
Mac_W
Author by

Mac_W

I'm Mac and I work as a Frontend Developer.

Updated on July 17, 2022

Comments

  • Mac_W
    Mac_W almost 2 years

    I'm using a shareDataService using BehaviorSubject like below. My problem is that every time I call the service's next() method the listener subscription in any other component is called several times, looks like it received the same message several times. Is this expected behavior? How to prevent it?

    The service is a singleton. I do not call changeMessage multiple times

    @Injectable()
    export class ShareDataService {
    
        messageSource = new BehaviorSubject(someData);
        currentMessage: Observable = this.messageSource.asObservable();
        changeMessage(message) {
            this.messageSource.next(message);
        }
    
    }
    

    Subscription in component

    ngDoCheck() {
        this.shareDataService.currentMessage
            .pipe(takeUntil(this.ngUnsubscribe))
            .subscribe((message) => {
                //Do stuff
            }
        });
    }