question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add 'skipNavigation' boolean to routerLink to disable navigating

See original GitHub issue

🚀 feature request

Relevant Package

This feature request is for @angular/router (specifically the routerLink directive)

Description

At the moment it doesn’t seem possible to combine the power of routerLinkActive (for class changes) with a routerLink that doesn’t navigate.
This can be useful for instance when you have a navigation of multiple levels, and only the child levels are allowed to actually navigate (but you still want to leverage the routerLinkActive directive to add/remove classes on the links that shouldn’t navigate.

Describe the solution you’d like

  • Add skipNavigation to the routerLink directive to block the actual navigation of the onClick handler.
  @HostListener('click', ['$event.button', '$event.ctrlKey', '$event.metaKey', '$event.shiftKey'])
  onClick(button: number, ctrlKey: boolean, metaKey: boolean, shiftKey: boolean): boolean {
    if (button !== 0 || ctrlKey || metaKey || shiftKey) {
      return true;
    }

    if (typeof this.target === 'string' && this.target !== '_self') {
      return true;
    }

    const extras = {
      skipLocationChange: attrBoolValue(this.skipLocationChange),
      replaceUrl: attrBoolValue(this.replaceUrl),
      state: this.state
    };
+    if(!attrBoolValue(this.skipNavigation)) {
+      this.router.navigateByUrl(this.urlTree, extras);
+    }
    return false;
  }

Describe alternatives you’ve considered

  • making the routerLink of the non-navigating links empty (or /) doesn’t help, since routerLinkActive will match all of them when using { exact: false }.
  • using {exact: true} works for not matching all the root levels, but this will in turn never actually show a clear view of what links are currently active based on the URL (current link + all it’s parents should be set to active, not only the clicked link).
  • good practice would be using a guard, but for this specific situation it seems to be quite the overkill when it can just be fixed with a boolean that is false by default (so doesn’t impact anything but the actual case).

Related Issues

#10431 #22588 #13980

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:26
  • Comments:11 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
simeylacommented, Nov 20, 2019

@jasonaden When a question is viewed on Stackoverflow over 63k times shouldn’t that give a request like this a bump?

Cancelling a link is something very fundamental to how people have learnt to make websites, and CanActivate / CanDeactivate are often too complex when you just need to stop the default action (for many reasons).

Something simple like (routerLinkClick) with parameters signature (urlTree, extras) would allow users to override the default onClick() handler and save thousands of hours looking for a solution. I’ve spent two hours today and probably another two hours a year ago on this exploring solutions.

I just can’t bring myself to clone the whole of the routerLink and routerLinkActive files for something so trivial.

I really hope someday this can be added. Thanks.

4reactions
fromsomniacommented, Aug 15, 2020

While a built-in solution is in the works (https://github.com/angular/angular/pull/35393), I’ve had success preventing unwanted navigation when invoking navigation through routerLink children of a container wielding a non-navigational routerLink attribute (for routerLinkActive functionality). Apply the following directive to the container with the non-navigational routerLink attribute:

import {Directive, ElementRef, Input, OnDestroy, Renderer2} from "@angular/core";

@Directive({
	selector: "[skipNavigation][routerLink]",
})
export class SkipNavigationDirective implements OnDestroy {

	@Input() public skipNavigation = false;

	private unsubscribe: () => void;

	constructor(private ref: ElementRef, private renderer: Renderer2) {
		this.unsubscribe = renderer.listen(ref.nativeElement as HTMLElement, "click", (event: MouseEvent) => {
			if (this.skipNavigation) {
				event.stopImmediatePropagation();
			}
		});
	}

	public ngOnDestroy(): void {
		this.unsubscribe();
	}
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

How can I conditionally disable the routerLink attribute?
If routerLink links to the active route, the class which is specified in routerLinkActive will be applied. That will be is_disabled in this...
Read more >
RouterLink - Angular
Navigation opens one or more routed components in one or more <router-outlet> ... i.e. ['/route']; null|undefined: effectively disables the routerLink.
Read more >
Mastering RouterLink - Briebug Blog
The goal here is to give a comprehensive introduction to the topic of routing via the Angular template using the RouterLink directive.
Read more >
ASP.NET Core Blazor routing and navigation - Microsoft Learn
GetUriWithQueryParameter to add, change, or remove one or more query ... InvokeAsync<bool>("confirm", "Are you sure you want to navigate to ...
Read more >
Part 2 | routerLink and Routing Guards in Angular - YouTube
Angular Router enables user to navigate from one view to the next for a better user experience. The routerLink can be used for...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found