Issue
How to bind data between services and components in real time way.
let's suppose isAuthenticated
a public variable for Authentication service that is affecting some view in a component. My question is how to subscribe to isAuthenticated
variable?
Service:
import { Injectable } from '@angular/core';
@Injectable()
export class Authentication {
isAuthenticated:boolean = false;
login() {
localStorage.setItem('access_token', 'true');
this.isAuthenticated = true;
}
}
Component:
...
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private isAuthenticated:boolean = false;
constructor(public authService: Authentication) {
this.isAuthenticated = this.authService.isAuthenticated'
}
}
home.html
...
<div *ngIf="isAuthenticated">Authentication view</div>
<div *ngIf="!isAuthenticated">Unauthentication view</div>
...
By the current flow above, the binding is working well but isn't real time.
So what is the best approach:
1- Create an observable inside the Authentication service in order to subscribe to it inside the component.
2- Binding using the following way:
...
<div *ngIf="authService.isAuthenticated">Authentication view</div>
<div *ngIf="!authService.isAuthenticated">Unauthentication view</div>
...
The second approach is working well but I don't know if it is the best practice.
Thanks.
Solution
I would recommend using BehaviorSubject
. It's an Observable
, so you can subscribe to it, but you can also control when it emits new values by calling behaviorSubject.next(newValue)
. When creating BehaviorSubject you must pass inital value to it. In your case it's false
.
@Injectable()
export class Authentication {
isAuthenticated = new BehaviorSubject<boolean>(false);
login() {
localStorage.setItem('access_token', 'true');
this.isAuthenticated.next(true);
}
}
-
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private isAuthenticated:boolean;
constructor(public authService: Authentication) {
this.authService.isAuthenticated
.subscribe(isAuthenticated => this.isAuthenticated = isAuthenticated)
}
}
or you can subscribe in html with Async Pipe
export class HomePage {
private isAuthenticated: BehaviorSubject<boolean>;
constructor(public authService: Authentication) {
this.isAuthenticated = this.authService.isAuthenticated;
}
}
-
<div *ngIf="isAuthenticated | async">Authentication view</div>
<div *ngIf="!(isAuthenticated | async)">Unauthentication view</div>
Unlike regular Observable, when you call subscribe on BehaviorSubject, the function you passed as an argument to subscribe will be immediately executed. This is because BehaviorSubject always has a value. You can access it with this.authService.isAuthenticated.value
but it's not very useful here.
Answered By - displayName
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.