Search code examples
angulartypescriptsubscription

How do I prevent multiple subscription calls in Angular?


I have a message service, to interact between various components. I just want to trigger a message, when I click on the Mine button. This works so far. But when I click on the < and >button, it triggers getMessage(), so that it adds up values. But I just want to send one value, when I click on Mine. The last value only. How do I prevent to trigger getMessage(), when clicking on <and >?

When I click on <and >it switches between the cards from 1 to 10. When I click on Mine it should only take the card which I'm on and send the information from that block to another component. But instead, when I click <or >, getMessage()is getting called and it adds up all cards until I click Mine. How do I prevent that?

Following some code. I tried to keep it compact:

Message-service.ts:

@Injectable({ providedIn: 'root' })
export class MessageService {
  private subject = new Subject<any>();

  sendMessage(message: string) {
    this.subject.next({ text: message });
  }

  getMessage(): Observable<any> {
    console.log('Get Message Message Service');
    return this.subject.asObservable();
  }

Miner-card.component:

  message: any;
  subscription: Subscription;

  constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
              private messageService: MessageService) {
    this.subscription = this.messageService.getMessage().subscribe(message => {
      console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
    });
  }

When I click on <and >, these functions are getting called: Depending on the value of minerCounter, card 1-10 are getting displayed.

  precedingBlock() {
    this.minerCounter--;

    if (this.minerCounter < 1) {
      this.minerCounter = 10;
    }
  }

  nextBlock() {
    this.minerCounter++;

    if (this.minerCounter > 10) {
      this.minerCounter = 1;
    }
  }

How the card looks like with the <and >buttons:

enter image description here

The Mine button:

enter image description here


Solution

  • You should always unsubscribe the subscription in ngOnDestroy.

      message: any;
      subscription: Subscription;
    
      constructor(private ref: ChangeDetectorRef, private emitTransactionService: EmitTransactionService,
                  private messageService: MessageService) {
        this.subscription = this.messageService.getMessage().subscribe(message => {
          console.log('Constructor miner-card'); // gets called multiple times, depending on how often I click < and >. When I click 10 times on < or > it will call this subscription 10 times.
        });
      }
    
    ngOnDestroy() {
      this.subscription.unsubscribe();
    }