My AuthService manages login/logout functionality, checks user authentication status, and utilizes angular2-jwt
(specifically uses tokenNotExpired()
).
To ensure the AuthService functions as a singleton, I created a Module dedicated to this service.
Currently, I check if a user is logged in using the following approach:
<p *ngIf="authService.authenticated()">Text</p>
This method works as intended.
However, I aim to encapsulate this logic within its own directive so that components checking for user authentication status do not need to inject the AuthService.
The desired outcome is something like this:
<p *authenticated>Text</p>
The directive I created for this purpose looks like this:
@Directive({selector: "[authenticated]"})
export class AuthenticatedDirective {
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private auth: AuthService) {
}
@Input() set authenticated(condition: boolean) {
if (this.auth.authenticated()) {
console.log("IsLoggedIn");
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
console.log("NotLoggedIn");
this.viewContainer.clear();
}
}
}
This directive essentially replicates the functionality of *ngIf but without any parameters.
The issue I am facing is that the directive only runs when the site loads and does not continuously monitor this.auth.authenticated()
to determine if the token has expired.
Simply triggering change detection does not have any effect if the directive is not listening for it. Manually triggering it after, for example, a logout does not produce the desired result either.
I understand that I can listen for events within the directive using host or HostListeners, but I cannot find an event related to change detection that would allow me to update the directive.
In essence, my question is how can I listen for the change detection event or is there a better approach to wrapping
*ngIf="authService.authenticated()"
?
Thank you in advance.
UPDATE:
Following the suggestion from @Chrillewoodz, I recalled lifecycle hooks, specifically the DoCheck hook.
The updated solution for my directive now looks like this:
@Directive({selector: "[authenticated]"})
export class AuthenticatedDirective implements DoCheck {
private isAuthenticated = false;
constructor(private templateRef: TemplateRef<any>,
private viewContainer: ViewContainerRef,
private auth: AuthService) {
}
ngDoCheck() {
if (this.isAuthenticated !== this.auth.authenticated()) {
this.isAuthenticated = this.auth.authenticated();
if (this.auth.authenticated()) {
console.log("IsLoggedIn");
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
console.log("NotLoggedIn");
this.viewContainer.clear();
}
}
}
}