Reputation: 678
Here's my scenario:
A user visits a route called /protected
. In my CanActivate guard, I check whether the user is logged in. If they are not logged in, I want to render my 404
route, but still show /protected
in the address bar. I want users to be unable to distinguish a protected page from a non-existent page.
This is what I tried and does not work.
@Injectable()
export class LoggedInGuard implements CanActivate {
constructor(private router: Router, private userService: UserService) {}
canActivate() {
if (this.userService.getUser()) return true;
this.router.navigate(['/404']);
return false;
}
}
After routing, the url in the address bar will show /404
, but I want it to show /protected
.
Changing to this.router.navigate(['/404'], { skipLocationChange: true });
also does not work because the url in the address bar will be the previous url, not /protected
.
My question is: how do you render a different component if the user is not logged in while still keeping the url that they were trying to visit in the address bar?
Upvotes: 3
Views: 3280
Reputation: 46
The /protected
route should render the error component if the user isn't logged in, else render a different component.
Define a route and component for /protected
, /error
, and /page1
.
When the user lands on /protected
, navigate to /error
if they're not logged in, else /page1
.
Be sure to pass { skipLocationChange: true }
as the second argument to router to avoid the url from navigating away from /protected.
this.router.navigate([this.url], { skipLocationChange: true });
Adding a CanActivate()
check for /protected
determines if you can access the path or not. So it isn't useful in this case because you want to the path to be open but show different content.
https://plnkr.co/edit/6o2DPXmYfNiQEW2Kbr8A?p=preview
@Component({
selector: 'app-protected',
template: `
Location: {{href}} <br>
Checking Login state ...
<div *ngIf="url">Switching to {{url}}</div>
`,
})
export class AppProtected implements OnInit {
url : string;
href = window.location.href;
constructor(private router : Router ) {
}
ngOnInit(){
const isUserLoggedIn = /true/.test(localStorage.getItem('isUserLoggedIn'));
this.url = isUserLoggedIn ? '/page1' : '/error';
window.setTimeout(() => {
this.router.navigate([this.url], { skipLocationChange: true });
}, 2000);
}
}
Upvotes: 3