I'm using angular 2 rc1 and the new router @angular/router
In app component I have a nav section and router outlet
<nav>
<a *ngIf="auth?.userName == null" [routerLink]="['/login']">Login</a>
<a *ngIf="auth?.userName != null" (click)="logout()">Logout</a>
{{auth?.userName}}
</nav>
<router-outlet></router-outlet>
I inject a loginService into app component and subscribe to an event in ngOnInit
ngOnInit() {
this.loginService.loginSuccess.subscribe(this.loginSuccess);
}
ngOnDestroy() {
this.loginService.loginSuccess.unsubscribe();
}
private loginSuccess(res: IAuthResponse) {
this.auth = res;
}
when I navigate to my '/login' route page/component my loginService is inject and loginService defines an event
@Output() loginSuccess = new EventEmitter<IAuthResponse>();
and after successful login in my service, the login service raises the event
this.loginSuccess.next(response);
I'm able to set a breakpoint in app component on the subscribed loginSucess and the data is passed along, however 'this' is undefined.
private loginSuccess(res: IAuthResponse) {
this.auth = res; //this is undefind
}
how can I update the app component from events that are triggerd from services used in components that are hosted in the router outlet
Not sure what you mean by "and the data is passed".
@Output() loginSuccess = new EventEmitter<IAuthResponse>();
in the component added by the router (LoginComponent
) doesn't do anything.
@Input()
and @Output()
in routed components are not supported.
Just inject LoginService
to the routed component and emit the event using an observable in the login component.
@Injectable()
export class LoginService {
changes:BehaviorSubject = new BehaviorSubject(false);
}
export class LoginComponent {
constructor(private loginService:LoginService) {}
onLogin() {
this.loginService.changes.next(true);
}
}
export class NavComponent {
constructor(private loginService:LoginService) {}
onLogin() {
this.loginService.changes.subscribe(status => this.isLoggedIn = status);
}
}
This looks like it could be the solution to my problem: passing events from child to parent that uses router-outlet, however it looks like RC1 has changed how BehaviorSubject works. Using the method above:
changes:BehaviorSubject = new BehaviorSubject(false);
gives an error saying BehaviorSubject needs a type declaration, so I tried both
changes:BehaviorSubject<boolean> = new BehaviorSubject(false);
as well as
changes:BehaviorSubject<any> = new BehaviorSubject(false);
and it compiles fine, but when running the app, it gives a non-descriptive
error of:
zone.js:323 SyntaxError: Unexpected token <
Evaluating http://localhost:3000/node_modules/rxjs/index.js
Error loading http://localhost:3000/app/main.js
at SystemJSLoader.__exec
(http://localhost:3000/node_modules/systemjs/dist/system.src.js:1395:16)
at entry.execute
I'm assuming something has changed with rxjs and BehaviorSubject