Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 8 Cancel or do something before navigation starts

I have a scenario where I have a route

<a routerLink="/crisis-center" routerLinkActive="active">Crisis Center</a>

in the controller I would like to cancel the rout navigation based on a value.

export class HeroListComponent implements OnInit {
 cancelRoute : boolean = true

  constructor(
   //some logic where before the route is navigated to, I want it to cancel the route
   // and log a message to console
   //console.log('successfully, canceled route');
  ) {}

EDIT

I do not want this done through a Route Guard, i want this done at the component level. I have a component on the page, that I want to cancel route navigation.

here is my use case.

I have a page which hosts multiple components, If someone leaves the page I want to check with component A and make sure there isnt any unsaved data before they navigate away.

EDIT 2

"I do not want this done through a Route Guard". Why? This is essentially what the CanDeactivate guard exists for. You can definitely use it for your use case with ease.

Correct me If I am wrong, but I would need to put the CanDeactivateGuard On every route for example

RouterModule.forRoot([
  {
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: ['canDeactivateTeam']
  }

I do not want to have a CanDeactivate on every route, when Only 1 route have foo component inside.

There are many routes, only one route needs foo component and he need to can cancel the route navigation. As far as I know the canDeactivate route gaurd cannot access components created on a route.

EDIT 3

NavigationStart The docs state that this is an event that is fired. I can hook into that event, but I cannot stop the actually navigation. Unless I am wrong NavigatonStart just tells me when it starts navigating not how to stop the navigation.

like image 445
gh9 Avatar asked Oct 08 '19 18:10

gh9


People also ask

Which route Guard would you use to prevent a user from navigating to another view before saving their content?

CanDeactivate. A third type of guard we can add to our application is a CanDeactivate guard which is usually used to warn people if they are navigating away from a page where they have some unsaved changes.

How do I stop RouterLink?

Angular's standard way to enable/disable navigation from a given route is to implement a CanDeactivate route guard. Similarly, you can implement a CanActivate route guard to enable/disable navigation to a given route.

Can activate VS can deactivate angular?

What is difference between Angular CanActivate and CanDeactivate route guard and how to use them? Angular CanActivate and CanDeactivate are the route guards in Angular routing. CanActivate decides if a route can be activated. CanDeactivate decides if route can deactivated.


1 Answers

There is no other way to prevent from navigate with no DeactivateGuard, but! You can make him as injectable.

import { CanDeactivate } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { Injectable } from '@angular/core';

@Injectable()
export class DeactivateGuard implements CanDeactivate<HomeComponent> {

    canDeact = true

  canDeactivate() {
    return this.canDeact
  }
}

You can inject it to any component You want and change canDeact to false so You prevent from navigate to other route when job is not done. Still, on default canDeact is true, so if in your route there will be no component foo with will trigger ngOnInit which make guard false and prevent from navigate out.

so guard as above and setup canDeactivate in routing:

{
    path: 'team/:id',
    component: TeamComponent,
    canDeactivate: [DeactivateGuard]
}

Becouse of it is injectable provide it in some root module:

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [
    DeactivateGuard
  ],
  bootstrap: [AppComponent]
})
export class AppModule { }

Assuming, some times foo component will be inside TeamComponent. Just in foo component:

export class FooComponent implements OnInit {

  constructor(private deactGuard: DeactivateGuard) { }

  ngOnInit() {
    this.deactGuard.canDeact = false
  }

  jobDone() {
    this.deactGuard.canDeact = true
  }

}

Try to not paste foo component outside of TeamComponent range. Or develop it correct in ngOnInit so he will not make canDeact false when ever he want's to.

like image 61
Mises Avatar answered Nov 15 '22 12:11

Mises