-2

There is place where event is emitted:

private action: Subject<IActionData> = new Subject();

 apply(data?: IActionData) {
    this.action.next(data);
 }

I have component <app-word-block> where event is listen:

this.listener.changes().subscribe((res: IActionData) => {
   // Show type here
});

Problem is I reuse this component on the page like:

<app-word-block type="1"></app-word-block>
<app-word-block type="2"></app-word-block>
<app-word-block type="3"></app-word-block>

Therefore event listeners works three times.

How avoid rest of and listen only one event?

POV
  • 11,293
  • 34
  • 107
  • 201
  • 2
    If the component is displayed three times, but you only want to listen to changes once, then the code subscribing to the event should most probably not be in the component. Without knowing what you want to achieve, it's hard to say more than that. – JB Nizet Aug 07 '19 at 14:24
  • Don't you need every instance of the component to be updated with the new value they are listening to? – Morphyish Aug 07 '19 at 14:24
  • @OPV What is `this.listener`? – Florian Aug 07 '19 at 14:31
  • 2
    [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Vikas Aug 07 '19 at 14:34
  • What is the *problem* that is introduced by `// Show type here`. You've left out the example code that is causing the issue and then asked how to fix it. – Reactgular Aug 07 '19 at 14:42

1 Answers1

2

EDIT : After comments, I misunderstood your problem. My previous answer resolves this "My subscription is duplicate when i navigate in my application", if you are interested about this check it below. I can suggest some solutions :

  • You can do the subscription in your "parent component" and pass data in input directives
  • Use a service and do the subscription there and retrieve it in your component.

I will try to give you some example later.

EDIT 2 : As mentioned in your post's comment. If you use a component various times in the same template you should not subscribe to a subject in this component.

Parent subscription method : It's in the parent component you should do the subscription. We don't have your code so i will presume you need to send some data to your component i will show you the way with a rough example. ParentComponent :

ts :

import { Component, OnInit } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Component({
    selector: "app-parent",
    templateUrl: "./parent.component.html",
    styleUrls: ["./parent.component.scss"]
})
export class ParentComponent implements OnInit {
    private sub;
    private i = 0;
    private subject = new BehaviorSubject<any>(0);
    constructor() {}

    ngOnInit() {
        this.sub = this.subject.subscribe(data => {
            this.i = data;
        });
    }
    click() {
        this.i++;
        this.subject.next(this.i);
    }
    ngOnDestroy() {
        if (this.sub) {
            this.sub.unsubscribe();
        }
    }
}

html :

<app-child  [value]="i" ></app-child>
<app-child [value]="i" ></app-child>
<app-child  [value]="i"></app-child>
<app-child [value]="i" ></app-child>
<!-- button for testing if it works -->
<button (click)="click()">test</button>

Child component : ts :

import { Component, OnInit, Input } from "@angular/core";

@Component({
    selector: "app-child",
    templateUrl: "./child.component.html",
    styleUrls: ["./child.component.scss"]
})
export class ChildComponent implements OnInit {
    @Input() value;

    constructor() {}

    ngOnInit() {}
}

and finally html to check if the value is pass and sync.

<p>
  {{this.value}}
</p>

PREVIOUS ANSWER :

Subscription need to be unsubscribe or you will have multiple subscription as you mentioned. Your component need to implement (onDestroy)

   export class YourComponent implements OnInit,OnDestroy

you will need to import it

import { Component, OnInit,OnDestroy } from '@angular/core';

you have to set your subscription in a var to manipulate it later.

    this.sub = this.listener.changes().subscribe((res: IActionData) => {
   // Show type here
});

And then in your component you will need to have a function ngOnDestroy();

ngOnDestroy() {
    if (this.sub) { // check if it's defined sometimes you can get some trouble there,
      this.sub.unsubsribe();
    } 
}

You should watch about life cycle angular it's an important features of angular.

Nico
  • 518
  • 2
  • 11
  • 2
    You're right to mention it, however how is it related to OP's question ? – Florian Aug 07 '19 at 14:33
  • @Florian I may have misunderstood the problem. With a step back yep you are right. If he has 3 times the same components in the "parent component" it will trigger 3 times the sub. i will update the answser. – Nico Aug 07 '19 at 14:40