Reputation: 17138
I know this is hard to believe, but Observables are kind of tricky and I don't 100% get them. :-)
Given this code:
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;
private loggedIn = new BehaviorSubject<boolean>(this.tokenIsValid());
...
get isLoggedIn(): Observable<boolean> {
this.loggedIn.next(this.tokenIsValid());
return this.loggedIn.asObservable();
}
private tokenIsValid(): boolean {
let currentUser: User = this.currentUserValue;
if (currentUser) {
const token = currentUser.token;
const tokenInfo = this.getDecodedAccessToken(token);
if (Date.now() <= tokenInfo.exp * 1000) {
return true;
}
}
return false;
}
private getDecodedAccessToken(token: string): any {
try {
return jwt_decode(token);
} catch (Error) {
return null;
}
}
Why does isLoggedIn
report true
when it shouldn't only one time (the first time after logout), and then work perfectly thereafter?
Here's the sequence:
And by "see it", I mean I am not prohibited by my AuthGuard to see the page.
My question then is why the error only the first time?
ADDED: Here's the constructor for the AuthenticationService class, if that helps:
constructor(private httpClient: HttpClient) {
this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem(this.currUser)));
this.currentUser = this.currentUserSubject.asObservable();
}
Upvotes: 0
Views: 93
Reputation: 17762
I do not understand the full context of your question but I see a potential problem in this piece of code
get isLoggedIn(): Observable<boolean> {
this.loggedIn.next(this.tokenIsValid());
return this.loggedIn.asObservable();
}
Here it seems you are trying to do 2 things
this.loggedIn.next(this.tokenIsValid())
Subject
(as an Observable
) used to broadcast to all interested party the above notificationThe point is that every party (e.g. your AuthGuard) which wants to be notified when something happens first has to subscribe to the Observable it is interested in, and only then it gets any notification when the Observable emits.
This means that you have to find a way for your interested party to first subscribe to loggedIn
as Observable with something like
get isLoggedIn(): Observable<boolean> {
return this.loggedIn.asObservable();
}
and only then find the right place to make loggedIn
emit something via this.loggedIn.asObservable()
.
If rather the point is that you want to receive a notification for an event even if it has happened before the subscription, you have to use ReplySubject and not BehaviorSubject.
Upvotes: 1