I am stuck in a issue that happens when user manually changes the route in browser tab and presses enter. This forces my ui-router/angular2-router to navigate to the state entered by user. I want to prevent this and allow routing only through the flow I have implemented by button clicks in my website.
Redirect. When this button is clicked, we'll perform the URL change without loading the new route. import { Location } from '@angular/common'; 1import { Location } from '@angular/common';
Steps to detect route change in Angular application Urls. Import Router, Event, NavigationStart, NavigationEnd, NavigationError from '@angular/router'. And inject router in the constructor. Subscribe to the NavigationStart, NavigationEnd, NavigationError events of the router.
RouterLink is a built-in Angular Directive that lets you link to specific routes in your app. In the SPA(single-page application), you change what the user sees by showing or hiding portions of the display that correspond to particular components, rather than going out to the server to get a new page.
skipLocationChange: boolean. You can change the route, without changing the URL in the browser. This Navigates to a new URL without pushing a new state into history.
Its 2018! Angular 5 is here and so is the solution to this issue. BAMM its CanActivate Interface that a class can implement to be a guard deciding if a route can be activated.
We can add this functionality and prevent the access to some of our routes based on the conditions we define. A service for eg AuthGuard that implements the CanActivate interface and defines the canActivate method can be added to route configuration.
class Permissions {
canGoToRoute(user: UserToken, id: string): boolean {
return true;
}
}
@Injectable()
class AuthGuard implements CanActivate {
constructor(private permissions: Permissions, private currentUser: UserToken) {}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean>|Promise<boolean>|boolean {
return this.permissions.canGoToRoute(this.currentUser, route.params.id);
}
}
If we have a route that we want to protect access to against some condition, we add the guard as follows:
const appRoutes: Routes = [
{ path: 'crisis-center', component: CrisisListComponent },
{
path: 'heroes',
canActivate: [AuthGuard],
component: HeroListComponent,
data: { title: 'Heroes List' }
},
{ path: '',
redirectTo: '/heroes',
pathMatch: 'full'
},
{ path: '**', component: PageNotFoundComponent }
];
Here the route heroes
and all its children have a layer of guard over it. Hence based on the boolean value returned by the AuthGuard service the user will be allowed or denied access to this route.
You can import router in the constructor of a guard. This router instance will have the current URL. ActivatedRouteSnapshot and RouterStateSnapshot in canActivate will contain the URL that the user is attempting to access.
The below example prevents users from directly accessing a route from an outside page.
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class DirectAccessGuard implements CanActivate {
constructor(private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
// If the previous URL was blank, then the user is directly accessing this page
if (this.router.url === '/') {
this.router.navigate(['']); // Navigate away to some other page
return false;
}
return true;
}
}
Add this guard to your routing module
{ path: 'signup/:type/:step', component: SignupComponent, canActivate: [DirectAccessGuard] }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With