Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BehaviorSubject subscriber gets same next() element multiple times

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
        }
    });
}
like image 629
Mac_W Avatar asked Jan 02 '23 02:01

Mac_W


2 Answers

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();
}
like image 172
Jeffrey Roosendaal Avatar answered Apr 27 '23 12:04

Jeffrey Roosendaal


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

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

Hope this helps!

like image 40
David R Avatar answered Apr 27 '23 12:04

David R