I'm trying to fire an event when my ponent gets the logged user from a service because I would like to show the navigation bar only when a user is logged in.
Here's my appponent code:
import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import { LoginComponent } from './loginponent';
import { DashboardComponent } from './dashboardponent';
import { ControlDetailComponent } from './control-detailponent';
import { PageNotFoundComponent } from './pagenotfoundponent';
import { SettingsComponent } from './settingsponent';
import { UserService } from '../service/user.service';
import { User } from '../object/user';
@Component({
selector: 'myApp',
templateUrl: './app/template/appponent.html',
styleUrls: ['styles.css'],
directives: [ROUTER_DIRECTIVES],
prepile: [LoginComponent, DashboardComponent, ControlDetailComponent, PageNotFoundComponent, SettingsComponent]
})
export class AppComponent {
@Input() loggedUser:User;
@Output() userChanged:EventEmitter<User> = new EventEmitter<User>();
constructor(private _userService:UserService, private _router:Router) {}
ngAfterViewInit() {
if(this._userService.isUserLogged()) {
this.userChanged.emit(this._userService.loggedUser);
}
}
switchUser(event) {
this.loggedUser = event.target.value;
console.log("event triggered");
}
}
And this is its associated template:
<div class="all-content">
<nav (userChanged)="switchUser($event)" *ngIf="loggedUser">
<ul>
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
<a [routerLink]="['/settings']" routerLinkActive="active">Settings</a>
<a (click)="logout()">Logout</a>
</ul>
</nav>
Someone knows why my event is not fired?
Initially I thought the problem was the *ngIf
directive that was preventing the firing of the event but, even removing that, the event is not fired anyway...
I'm trying to fire an event when my ponent gets the logged user from a service because I would like to show the navigation bar only when a user is logged in.
Here's my app.ponent code:
import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import { LoginComponent } from './login.ponent';
import { DashboardComponent } from './dashboard.ponent';
import { ControlDetailComponent } from './control-detail.ponent';
import { PageNotFoundComponent } from './pagenotfound.ponent';
import { SettingsComponent } from './settings.ponent';
import { UserService } from '../service/user.service';
import { User } from '../object/user';
@Component({
selector: 'myApp',
templateUrl: './app/template/app.ponent.html',
styleUrls: ['styles.css'],
directives: [ROUTER_DIRECTIVES],
prepile: [LoginComponent, DashboardComponent, ControlDetailComponent, PageNotFoundComponent, SettingsComponent]
})
export class AppComponent {
@Input() loggedUser:User;
@Output() userChanged:EventEmitter<User> = new EventEmitter<User>();
constructor(private _userService:UserService, private _router:Router) {}
ngAfterViewInit() {
if(this._userService.isUserLogged()) {
this.userChanged.emit(this._userService.loggedUser);
}
}
switchUser(event) {
this.loggedUser = event.target.value;
console.log("event triggered");
}
}
And this is its associated template:
<div class="all-content">
<nav (userChanged)="switchUser($event)" *ngIf="loggedUser">
<ul>
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
<a [routerLink]="['/settings']" routerLinkActive="active">Settings</a>
<a (click)="logout()">Logout</a>
</ul>
</nav>
Someone knows why my event is not fired?
Initially I thought the problem was the *ngIf
directive that was preventing the firing of the event but, even removing that, the event is not fired anyway...
2 Answers
Reset to default 3Events emitted by @Output()
s can only be subscribed to on the parent ponent or a directive applied on the element. The AppComponent
doesn't have a parent ponent, therefore this approach won't work.
In your case it's better to use a shared service with observables. https://angular.io/docs/ts/latest/cookbook/ponent-munication.html
Solved using Observables
and a Service
, as Günter Zöchbauer suggested (thanks!).
Below my solution:
user.service.ts
import { Injectable } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { Subject } from 'rxjs/Subject';
import { Control } from '../object/control';
import { User } from '../object/user';
@Injectable()
export class UserService {
private userChangedSource = new Subject<User>();
userChanged = this.userChangedSource.asObservable();
loggedUser:User;
userLoggedIn(user:User) {
this.loggedUser = user;
this.userChangedSource.next(user);
}
...
}
app.ponent.ts
import { Component, OnInit, EventEmitter, Input, Output } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { ROUTER_DIRECTIVES, Router } from '@angular/router';
import { LoginComponent } from './login.ponent';
import { DashboardComponent } from './dashboard.ponent';
import { ControlDetailComponent } from './control-detail.ponent';
import { PageNotFoundComponent } from './pagenotfound.ponent';
import { SettingsComponent } from './settings.ponent';
import { UserService } from '../service/user.service';
import { User } from '../object/user';
@Component({
selector: 'myApp',
templateUrl: './app/template/app.ponent.html',
styleUrls: ['styles.css'],
directives: [ROUTER_DIRECTIVES],
prepile: [LoginComponent, DashboardComponent, ControlDetailComponent, PageNotFoundComponent, SettingsComponent]
})
export class AppComponent implements OnInit {
loggedUser:User;
constructor(private _userService:UserService, private _router:Router) {
this._userService.userChanged.subscribe(user => {
this.loggedUser = user;
console.log("event triggered");
});
}
...
}
app.ponent.html
<div class="all-content">
<nav *ngIf="loggedUser" >
<ul>
<a [routerLink]="['/dashboard']" routerLinkActive="active">Dashboard</a>
<a [routerLink]="['/settings']" routerLinkActive="active">Settings</a>
<a (click)="logout()">Logout</a>
</ul>
</nav>
<router-outlet></router-outlet>
<br/>
</div>