RxJs Subject getting multiple values on subscribe

2.6k views Asked by At

I have a Subject in my Angular Service like this:

private sub = new Subject();


sendSub(page: page) {
    this.sub.next(page);
}

getSub(): Observable<any> {
    return this.sub.asObservable();
}

In my parent component I have subscribed to getSub(). From my child component I'm sending one next value but in the parent I'm getting two values in subscription.

Need only one value so that my code block executes only once:

subscription: Subscription;

this.subscription = this.pageService
    .getSub()
    .subscribe(
        (data) => {
            this.data = data;
            this.nextSelection();
        }
    );
3

There are 3 answers

1
Anusha kurra On

Add Subscribe code in the constructor of the parent component.Here is a fiddle of the same

this.appService
    .getSub()
    .subscribe(
        (data) => {
             this.data = data;
             this.nextSelection();
        }
    );
1
AudioBubble On

Change

getSub(): Observable<any> {
  return this.sub.asObservable();
} 

to

getSub: Observable<any> = this.sub.asObservable();

This ensures that every subscriber uses the same subject.

0
Aniket On

The reason for getting multiple values after the first emit/next of a subject is that you might be subscribing everytime that subject whenever your function gets called.

For e.g.

detail$ = new Subject<UserDetail>();

getUserDetail() {
   detail$.subscribe({ next: res => {} })
}

If you are calling getUserDetail on the button click or any event then the same subject gets subscribed multiple times so the count of observers for that subject is getting increased. So, next time it will emit value to all the observers subscribed till now.

So removed your subscribe code from the place where it can be called multiple times. Either you can put it in constructor or some other place like ngOnInit and just simply next or emit value and that one observer will handle the task that needs to be done.

You can also destroy the subject once you get the next value in this case next time there will be no previous observer.

There is one more method you can use take(1) rxjs operator inside pipe operator, which will take the last value and unsubscribe that subject behalf of you.