2

We have an Angular 2 app using RouterModule. We wrote a simple service that looks like this:

//imports...
@Injectable()
export class ActionService {

    actionClick: EventEmitter<any> = new EventEmitter();
    click() {
        this.actionClick.emit();
    }

    getActionEmitter() {
        return this.actionClick;
    }
}

We have a component called 'BaseStepComponent', which uses the ActionService:

//imports...
export class BaseStepComponent{
    subscription;

    constructor (protected actionService: ActionService){
        this.subscription = this.actionService.getActionEmitter()
        .subscribe(() => this.actionClicked())
    }

    actionClicked() {
        console.log("Action Clicked!");
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}  

The BaseStepComponent is a base class for other components, FirstStepComp and SecondStepComp. Our problem is that each time we navigate between those two components, another observer is added to the actionService, but the unsubscribe doesn't seem to work. Assuming we call ActionService.click() after each navigation (including the first), we expect to see one log message every time. But after the second navigation we see two message, three messages after the 3rd nav, and so on. We tried to call

super.ngOnDestroy() 

from the children's ngOnDestroy, but it didn't work. What are we missing?
Thanks!

Update - our Routing

Here is how we configured our routing: we have a component called ProgressComponent:

{path: 'progressComp/:step', component: ProgressComponent},
//other routes...

The HTML template of ProgressComponent:

<FirstStepComp *ngIf="curStep == 1">...</FirstStepComp>
<SecondStepComp *ngIf="curStep == 2">...</SecondStepComp>

To advance a step, ProgressComponent.ts navigates to itself with the new step number:

advance() {
     this.router.navigate([`../${this.curStep + 1}`], { relativeTo: this.route });
}

Just to clarify - we have other components that uses the ActionService, and the unsubscribe() works normally there.

Roy Millo
  • 103
  • 1
  • 5
  • Can you confirm that `ngOnDestroy` is called? You may want to show a live example. – Frank Modica Jun 18 '17 at 23:19
  • Can you show where did you provide the service? – brijmcq Jun 19 '17 at 00:49
  • I could not reproduce this locally. But I was only using 2 simple routes. Do you have nesting? – Frank Modica Jun 19 '17 at 01:26
  • @Frank `ngOnDestroy` is called, we can see logged messages from that function. I update the question with more details about our routing. Thank you for trying to reproduce, if the extra details are still not enough we'll create a plunkr. – Roy Millo Jun 19 '17 at 06:52
  • I haven't looked deep into your question but I suggest you to read this: https://stackoverflow.com/questions/36076700/what-is-the-proper-use-of-an-eventemitter **don't use EventEmitter in your services** – eko Jun 19 '17 at 06:54
  • It is not recommended to use `EventEmitter` in services. `EventEmitter` is designed for `@Output` properties on components. Services should publish observables. –  Jun 19 '17 at 08:17
  • @torazaburo can you explain a bit how to 'listen' to the observer from the class (ts file), and not through ``? – Roy Millo Jun 19 '17 at 08:59

0 Answers0