I'm want to add a alert dialog before the user click on the <a href="...">
link.
There are 2 types of <a>
link
<a routerLink="/path/to/dest">
<a href="http://www.somewhere.com" target="_blank">
I want to able to show an alert box when user try to go outside of Angular scope
I want to apply to all <a>
click event (kind like pre-hook)
Any way to achieve this?
Some of the useful events are route change start ( NavigationStart ) and route change end ( NavigationEnd ). In this tutorial, we learn what is router events are and how to listen to them using Example code. Applies to: Angular 2 to the latest edition of i.e. Angular 8. Angular 9, Angular 10, Angular 11, Angular 12
The Angular Route r raises events when it navigates from one route to another route. It raises several events such as NavigationStart, NavigationEnd, NavigationCancel, NavigationError, ResolveStart, etc.
Detecting Route state changes can be done by subscribing to the router and listening to the events being emitted. In the example below, you will see all the router events that you can listen to in Angular 8.
the Angular router stats the navigation. the Router lazy loads a route configuration. after a route has been lazy-loaded. the Router parses the URL and the routes are recognized. the Router begins the Guards phase of routing. the Router begins activating a route's children.
For links to other views of your Angular application, you can implement a CanDeactivate route guard. You will find an example in this stackblitz, for the "Home" page.
The links that navigate outside of the application should trigger the event handler bound to window:beforeunload
(shown in HomeViewComponent below). However, its behavior seems to be different in Firefox (a confirmation box is shown) and in Chrome (no confirmation box shown). That event cannot be tested with stackblitz, as far as I can see.
In app.module:
...
import { AppRoutingModule } from './app.routing.module';
import { DeactivateGuard } from './views/home/deactivate-guard';
@NgModule({
imports: [
AppRoutingModule,
...
],
providers: [
DeactivateGuard
],
...
})
In app.routing.module:
...
import { RouterModule } from '@angular/router';
import { DeactivateGuard } from './views/home/deactivate-guard';
@NgModule({
imports: [
RouterModule.forRoot([
...
{
path: 'home',
component: HomeViewComponent,
canDeactivate: [DeactivateGuard]
},
...
])
],
exports: [
RouterModule,
],
...
})
In home/deactivate-guard:
import { CanDeactivate } from '@angular/router';
import { HomeViewComponent } from './home.component';
export class DeactivateGuard implements CanDeactivate<HomeViewComponent> {
canDeactivate(component: HomeViewComponent) {
return component.canDeactivate();
}
}
In home.component:
import { Component, HostListener } from '@angular/core';
...
@Component({
...
})
export class HomeViewComponent {
@HostListener("window:beforeunload", ["$event"]) unloadHandler(event: Event) {
event.returnValue = false;
}
canDeactivate() {
return confirm("Do you want to leave?");
}
...
}
so Angular provides canActivate to make sure if you want to activate the route or not based on certain condition. You can
const routes: Routes = [
{path: '/some-path', canActivate:[AuthGuard]}
];
Your canActivate service
import { Injectable } from '@angular/core';
import { CanActivate, CanActivateChild } from '@angular/router';
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild {
canActivate() {
//ask if he really wants to route.
console.log('i am checking to see if you are logged ')
return true;
}
canActivateChild() {
console.log('checking child route access');
return true;
}
}
In the canActivate you can display a generic model to ask whether he wants to route to URL or not, and based on that you can control which link can have it and which not. You can even write logic for all the routing whether it be coming from anchor tag or anything else.
You can implement route guard which checks for your condition and then decide whether to redirect to clicked url or not depending upon your choice.
If you are following angular cli then you can simply install route guard by running :
ng g guard my-new-guard
Import guard file in app.module.ts and add it into providers array. In routing file add route guard to the paths on which you want to check for the condition. Like :
const appRoutes: Routes = [
{path: '/your-path', canActivate: [route-guard]}
];
In your route-guard file you can implement your logic like this :
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class AuthGuardGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if(!state.url.startsWith('/')){
// I have check here for starting single slash for all your angular local routes. You can also check for http or https whichever you want according to your need
// here you can trigger your modal pop-up on its 'OK' button return true to redirect to the url
return true; // or return false on 'Cancel' button of modal pop-up for cancelling route if condition doesn't fullfill
}
}
}
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