6

I have an issue where the EventEmitter does not output the value to parent component. Here is how i am setup.

main.component.ts (short version)

...     

@Component({
selector: 'my-app',
templateUrl: '/app/views/main.ejs',
directives: [ROUTER_DIRECTIVES],
providers:[AuthService],
inputs:['userLoggedIn']
})

@RouteConfig([
{path:'/logout', name: 'Logout', component: AuthComponent},

])

export class AppComponent implements OnInit, CanReuse{  

    constructor(private _auth_service: AuthService){

         this._auth_service.authChanged.subscribe(data=>this.authChangedHandler(data));

    }

    public authChangedHandler($event){

        alert($event);

    }

}

...

auth.component.ts (short version)

export class AuthComponent implements OnInit, CanReuse{

public loggedIn = false;

public user = {};

@Output()
authChanged: EventEmitter<string>;

public selectedTab = "/login";

    constructor(private _router: Router, private _location:Location,private _http: Http, private _auth_service: AuthService){

        this.authChanged = new EventEmitter();

        this.authChanged.emit("authChanged");

    }

}

main.ejs (short version)

<nav (authChanged)="authChangedHandler($event)"></nav>
<router-outlet></router-outlet>

auth.service.ts

export class AuthService {

public authChanged: EventEmitter<string>;

constructor(private _http: Http){

    this.authChanged = new EventEmitter();
    this.authChanged.emit("authChanged");

    }

}

EDIT: I have added AuthService code which i inject into main component. It should work now but does not.

4
  • Did you get a solution for it ? I am also looking to capture an event which is emitted from the component added in @RouteConfig Commented Feb 20, 2016 at 3:26
  • @Sanjeev Yes i did. I used Service Events. I have a created a plunker here (plnkr.co/edit/WZ5HbvBP5LMSqZQtixoG?p=preview) Commented Feb 20, 2016 at 5:41
  • The idea is to inject a Service at bootstrap and that service will contain the eventemitter which every component can subscribe to, globally. Commented Feb 20, 2016 at 5:42
  • thanks @R. Hussain: but it ll be great if there is a way to bubble up the event. Commented Feb 20, 2016 at 8:57

2 Answers 2

14

Events emitted by EventEmitter don't bubble. If the element is added to a router-outlet only the router-outlet receives the event but not the element containing the router-outlet.

You could use a shared service to communicate between the parent and the child element.

For shared service see

If you register the shared service in the providers: [] list of the parent component, the service is shared only between the parent element and all of its descendants. If you only add it to bootstrap(MyApp, [ ..., SharedService]) the whole application shares one instance.

Sign up to request clarification or add additional context in comments.

6 Comments

Could you please be more elaborate about the shared service? Maybe some code?
Yes i saw and i opted for Service Events and made changes to above code. Please see my edits.
If you emit the event in the constructor of the AuthService the event is alredy sent before AppComponent can subscribe. For the test wrap the emit(event) in AuthService in a setTimeout() to give AppComponent time to subscribe. In a real-world application it would fire later anyway.
Well, i have already tried emitting inside a logout method in AuthService but to no avail :(
@GünterZöchbauer: you are right, but isn't there any way to bubble up the event to the element containing the router outlet ?
|
1

In fact, the nav isn't the parent component of the AuthComponent one. The latter is involved in routing (see router-outlet). That's why you can't receive the event for the registered expression on the nav element in the HTML.

4 Comments

Please see my edits. The nav issue should not matter now since i'm using Service Events. Right?
Yes, but you should use this: this._auth_service.authChanged.emit('authChanged'); ;-) to trigger the event...
But i emit it from the service. Not from the component.
Oh sorry! Perhaps your service isn't completely a shared one (I mean by the whole application). To be sure, set it as provider when bootstrapping your application: bootstrap(AppComponent, [ AuthService ]);. Don't forget to remove it from providers attributes you can have at the level of your components. This is because of hierarchical injectors. See this answer for more details: stackoverflow.com/questions/34804298/….

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.