In my application I have some components that communicate by means of EventService
.
@Injectable()
export class EventService {
public myEvent: EventEmitter<any> = new EventEmitter();
constructor() {}
}
This service is injected in a EmitterComponent
that emits the event when a button is clicked
@Component({
selector: 'emitter',
template: `<button (click)="onClick()">Click me</button>`,
})
export class EmitterComponent {
constructor(private eventService:EventService) {}
onClick() {
this.eventService.myEvent.emit();
}
}
and in a ReceiverComponent
that subscribes to the event and for each event received increments a counter
@Component({
selector: 'receiver',
template: `Count: {{count}}`,
})
export class ReceiverComponent {
public count = 0;
constructor(private eventService:EventService) {
this.eventService.myEvent.subscribe(() => this.count++;);
}
}
The application has multiple views (in this example just two): PageA
and PageB
. EmitterComponent
and ReceiverComponent
are in PageA
. Every time I go to PageB
and come back to PageA
, a new ReceiverComponent
is created and when I click the button in EmitterComponent
, the event callback function of ReceiverComponent
is executed several times.
To avoid this I unsubscribe ReceiverComponent
from myEvent
in ngOnDestroy
ngOnDestroy() {
this.eventService.myEvent.unsubscribe();
}
but this causes the following Exception
EXCEPTION: Error during instantiation of ReceiverComponent!.
ORIGINAL EXCEPTION: Error: Cannot subscribe to a disposed Subject
How can I avoid that? How to unsubscribe correctly?
For a better understanding I've created this plunker where you can see the error and some comments in the console.
You get a subscription from .subscribe()
. Use its unsubscribe()
method to cancel the subscription.
@Component({
selector: 'receiver',
template: `Count: {{count}}`,
})
export class ReceiverComponent {
public count = 0;
private subscription;
constructor(private eventService:EventService) {
this.subscription = this.eventService.myEvent.subscribe(() => this.count++;);
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
See also