I'm coming form NG1 environment and currently I'm creating NG2 app with all available features. Before asking I was exploring google and stackoverflow questions but with no luck since angular 2 moved so fast with api architecture and most answers are out of date.
My case: I have Auth provider (service) with property user, I would like to observe user and react in multiple components (navbar, sidebar etc.)
What I tried:
@Injectable();
export class Auth {
private user;
authorized: EventEmitter<boolean>;
constructor(public router:Router){
this.authorized = new EventEmitter<boolean>();
}
login(user, token):void{
localStorage.setItem('jwt', token);
this.user = _.assign(user);
this.authorized.emit(<boolean>true);
this.router.parent.navigateByUrl('/');
}
}
/***************/
@Component({...})
export class NavComponent {
public isAuthroized: boolean = false;
constructor(Auth:Auth){
Auth.authorized
.subscribe((data) => this.onUserChanged(data));
}
onUserChanged(user){
alert('USER:' + user.email);
this.isAuthroized = true;
}
}
/****************/
bootstrap(AppComponent, [
ROUTER_PROVIDERS,
ELEMENT_PROBE_PROVIDERS,
HTTP_PROVIDERS,
MapLoader,
Auth
])
But with no luck. Should I use Observable EventEmitter or maybe there is other correct approach to handle this case? In NG1 it would be as simple as set $watch on service's property. Thanks!
EDIT: I added new method to Auth service:
...
userUpdated: EventEmitter<boolean>;
constructor(public router:Router){
this.userUpdated = new EventEmitter<any>();
}
...
logout(returnUrl?: string): void{
delete this.user;
localStorage.removeItem('jwt');
this.userUpdated.emit(undefined);
if(!_.isEmpty(returnUrl)){
this.router.parent.navigateByUrl(returnUrl);
}
}
And now event is called, why is this working for logout and not for login?
EDIT 2:
export class LoginPageComponent {
error: string;
constructor(public http: Http, public router: Router, public Auth:Auth){
}
login(event, email, password){
...
this.http.post('/api/login', loginModel, {headers: headers})
.map((res) => res.json())
.subscribe((res: any) => {
this.Auth.login(res.user, res.ADM_TOKEN);
}, (error) => this.error = error._body);
}
}
RESOLVED
Silly mistake.. i left in NavComponent in providers array [Auth].. so it was different object than global Auth.. sorry guys! Hope this issue will help somebody new in Angular2. Thanks for your effort.
I assume you are adding
Auth
as provider to every component. This creates a new instance of the class for each component. Add it only inbootstrap(AppComponent, providers: [...])
or only on theAppComponent
.You can notice that there is no watch feature in Angular since it's now managed by Zones.
To notify other components, you could add another
EventEmitter
within yourAuth
service for theuserUpdated
event. The components that want to be notified could register on this emitter.Components could register on this event:
You could also provide the user when emitting the
authorized
event:Hope it helps you, Thierry