bobbyrne01
bobbyrne01

Reputation: 6735

Prevent navigation on anchor that has routerLink

In my markup, there is [routerLink]="(onLink | async).linkURL"

And when its there, I'm unable to stop the navigation from happening when user clicks it.

If I remove [routerLink]="(onLink | async).linkURL", the navigation is stopped as expected.

Is there a way I can stop the navigation here? I'm unable to remove [routerLink]="(onLink | async).linkURL" from the markup.

My js below is not run in the angular context btw, its plain js.

Html ..

<div>
    <a id="myLink" [routerLink]="(onLink | async).linkURL">My link</a>
</div>

Javascript ..

document.getElementById('myLink').addEventListener('click', function(event) {
  console.log('click');
  event.preventDefault();
  event.stopPropagation();
});

Upvotes: 4

Views: 10082

Answers (4)

Dave A-W
Dave A-W

Reputation: 667

In your comments under the original question you ask us to "... assume there is a toggle in the UI that disables [the navigation]".

A method I've found is to disable pointer events using css. You get to keep your routerLink and routerLinkActive css class logic, but your users won't see the navigation link down in the browser status bar, and they won't be able to click the link to navigate.

<div>
  <a id="myLink"
     [routerLink]="(onLink | async).linkURL"
     [routerLinkActive]="active"
     [style.pointer-events]="toggledOn ? 'auto' : 'none'">
    My link
  </a>
</div>

Upvotes: 0

Mudassar Mustafai
Mudassar Mustafai

Reputation: 118

You can use this navigation logic on the component. You can add (click)=" method()" method on the anchor tag and add logic on the component method. I faced this issue and added logic on the component and used return in case I want to stop navigation.

I used router in component. this.router.navigate([]);

Upvotes: 0

Martin Parenteau
Martin Parenteau

Reputation: 73721

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.

An example of a CanDeactivate route guard is shown in this stackblitz, where the state of a check box allows or prevents navigation from the "Home" page.

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:

export class HomeViewComponent {

  allowNavigation = true;

  canDeactivate() {
    return this.allowNavigation;
  }
}

Upvotes: 1

Armen Vardanyan
Armen Vardanyan

Reputation: 3315

If you really cannot remove the [routerLink] and replace it with a (click) listener to handle the logic in a class method, maybe give this a try. In your component class:

shouldNavigate: boolean = false; // indicated whether it is possible to navigate
constructor(public route: ActivatedRoute) {} 

And inside the HTML template:

<a [routerLink]="shouldNavigate ? (onLink | async).linkURL : route.url">My link</a>

In Angular, if anchor points to the same url the user is now on, the navigation will not occur, so depending on the circumstances, change the url to the current page's url and be done with it.

Other options: you can write a directive that handles navigation or so. Let me know if this answer is not satisfying enough, so I may pick up another approach. This one is by far the laziest.

Upvotes: 0

Related Questions