I have created a Auth Manager in Angular2 to restrict Component access directly .
I am still new to angular and learning the concepts.
I was able to restrict the user if the user name is not correct.
But i am not able to use the value returned by the canActivate Method in my component to display a message in my front end.
My AuthManager class
import { Injectable } from '@angular/core';
import { CanActivate,Router,ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router';
@Injectable()
export class AuthManager implements CanActivate{
user = "user";
constructor(private router:Router){
}
canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
console.log("Comes Here");
if(this.user == "user"){
return true;
}else{
console.log("YOur are not authorized");
this.router.navigate(['/persons']);
return false;
}
}
}
I am able to see YOur are not authorized in log but how to use the value in a component.
My app.router.ts
{
path: 'persons/:id',
component: PersonDetailComponent,
canActivate:[AuthManager]
}
What i understood by the Question is that you want to display Some kind of Error Message to the User if the Auth Fails.
@PierreDuc is correct.But i have a different approach to this.
what you can do is create a service class
authenticate.service.ts
import {Injectable} from '@angular/core'
@Injectable()
export class AuthenticateService
isAuthenticated(//take the user credentials here):boolean{
return true // if the credentials are correct
or retun false // if the credentials donot match.
}
make use of this class in your component and AuthManager
import { Injectable } from '@angular/core';
import { CanActivate,Router,ActivatedRouteSnapshot,RouterStateSnapshot } from '@angular/router';
import {AuthenticateService} from './authenticate.service'
@Injectable()
export class AuthManager implements CanActivate{
user = "user";
constructor(private router:Router,private authenticateService:AuthenticateService){
}
canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
console.log("Comes Here");
return this.authenticateService.isAuthenticated();
}
}
and in the component check the same
this.authenticateService.isAuthenticated()== false
*ngIf and then display an error message to the user.
Hope this is what you where looking at . it not exactly the answer of the question but a way to solve your problem.
You can use service and set the value you want to display in component inside the AuthManager.
That's quite an uncommon thing to do, but I understand why you would want something like that. It is however not possible to capture the result returned from CanActivate
.
However you could make an ErrorService
and subscribe a component to an triggered event to show a toast message or something like that.
untested code ahead
@Injectable()
export class AuthManager implements CanActivate{
user = "user";
constructor(private router:Router, private errorService: ErrorService){}
canActivate(route:ActivatedRouteSnapshot,state:RouterStateSnapshot){
if(this.user == "user"){
return true;
} else{
this.errorService.toastError("You are not authorized");
this.router.navigate(['/persons']);
return false;
}
}
}
Your error service would in basic look something like this, you should add this service to your root providers:
export class ErrorService {
public readonly error: Subject<string> = new Subject<string>();
public toastError(error: string): void {
this.error.next(error);
}
}
After that place a component inside your AppComponent
(or whatever you deem fit) and make it something like this:
@Component({
selector : 'error-toast',
template : `<div [innerHtml]="error" *ngIf="error"></div>`
})
export class ErrorToastComponent implements OnInit, OnDestroy {
public error: string = "";
private timeout: number = 0;
private errorSub: Subscription;
private readonly timer: number = 5000;
constructor(private errorService: ErrorService) {}
ngOnInit(): void {
this.errorSub = this.errorService.subscribe((error: string) => {
this.toastError(error);
});
}
ngOnDestroy(): void {
this.errorSub.unsubscribe();
this.cancelTimer();
}
private toastError(error): void {
this.cancelTimer();
this.error = error;
this.timeout = window.setTimeout(() => {
this.error = "";
}, this.timer);
}
private cancelTimer(): void {
if(this.timeout !== 0) {
clearTimeout(this.timeout);
this.timeout = 0;
}
}
}