Search code examples
angulartypescripteventemitter

What I am doing wrong with Angular2 EventEmitter?


I would like to create universal toast service with angular2 EventEmitter. I created a service and emit some data. I want to catch this data in component but it doesnt work :/

It is the service with must to emit event :

 import {EventEmitter, Injectable, Output} from "@angular/core";
 import {IAlert} from "../../types/interfaces/IAlerts";

@Injectable()
export class ExceptionsManagerConfig {
public getalert(): IAlert {
    return this._alert;
}

public setAlert(value: IAlert) {
    this._alert = value;
    this.alertChangeEvent.emit(value);
    console.log("set alert");
}

@Output() alertChangeEvent: EventEmitter<any> = new EventEmitter();
private _alert: IAlert;
}

And this is a component with must to catch event:

import {Component, OnDestroy, OnInit, Input, EventEmitter} from "@angular/core";
import {ExceptionsManagerConfig} from "../../../../sheard/settings/exeptions/exeptions.menager.service.config";
import {IAlert} from "../../../../sheard/types/interfaces/IAlerts";
declare const Materialize: any;

@Component({
    providers: [ExceptionsManagerConfig],
    selector: "toast-alert",
    templateUrl: "app/elements/components/construction/toast-alert/toast-alert.html",
})
export class ToastComponent implements OnInit, OnDestroy {
    ngOnInit(): void {
        this.exceptionsManagerConfig.alertChangeEvent.subscribe(alert => this.showToast(alert));
        console.log("toast");
    }

    ngOnDestroy(): void {
    }

    showToast = (alert: IAlert) => {
        console.log(alert.message);
    };

    constructor(private exceptionsManagerConfig: ExceptionsManagerConfig) {

        this.exceptionsManagerConfig.alertChangeEvent.subscribe(alert => this.showToast(alert));
    }
}

Of corse I have set service in main bootstrap file.

Maybe have you some tips for me how to solve my problem ?


Solution

  • EventEmitter is not supposed to be used in services. Use Observable or Subject instead. @Output() in a service is meaningless. @Output() is only supported in directives and components.

    Your code should do what you expect anyway. I assume the current problem is that you provide ExceptionsManagerConfig on multiple places which results in one component calling ExceptionManagerConfig.setAlert() on a different instance of ExceptionManagerConfig then the one injected to ToastComponent.

    You should provide ExceptionManagerConfig at the NgModule (if you use >= RC.5) or AppComponent to get the same instance injected everywhere.