[angular] Passive Link in Angular 2 - <a href=""> equivalent

In Angular 1.x I can do the following to create a link which does basically nothing:

<a href="">My Link</a>

But the same tag navigates to the app base in Angular 2. What is the equivalent of that in Angular 2?

Edit: It looks like a bug in the Angular 2 Router and now there is an open issue on github about that.

I am looking for an out of the box solution or a confirmation that there won't be any.

This question is related to angular routing angular2-routing angular-router

The answer is


You have prevent the default browser behaviour. But you don’t need to create a directive to accomplish that.

It’s easy as the following example:

my.component.html

<a href="" (click)="goToPage(pageIndex, $event)">Link</a>

my.component.ts

goToPage(pageIndex, event) {
  event.preventDefault();
  console.log(pageIndex);
}

In my case deleting href attribute solve problem as long there is a click function assign to a.


Here is a simple way

  <div (click)="$event.preventDefault()">
            <a href="#"></a>
   </div>

capture the bubbling event and shoot it down


An achor should navigate to something, so I guess the behaviour is correct when it routes. If you need it to toggle something on the page it's more like a button? I use bootstrap so I can use this:

<button type="button" class="btn btn-link" (click)="doSomething()">My Link</button>

you need to prevent event's default behaviour as follows.

In html

<a href="" (click)="view($event)">view</a>

In ts file

view(event:Event){
 event.preventDefault();
 //remaining code goes here..
}

That will be same, it doesn't have anything related to angular2. It is simple html tag.

Basically a(anchor) tag will be rendered by HTML parser.

Edit

You can disable that href by having javascript:void(0) on it so nothing will happen on it. (But its hack). I know Angular 1 provided this functionality out of the box which isn't seems correct to me now.

<a href="javascript:void(0)" >Test</a>

Plunkr


Other way around could be using, routerLink directive with passing "" value which will eventually generate blank href=""

<a routerLink="" (click)="passTheSalt()">Click me</a>

A really simple solution is not to use an A tag - use a span instead:

<span class='link' (click)="doSomething()">Click here</span>

span.link {
  color: blue;
  cursor: pointer;
  text-decoration: underline;
}

I have 4 solutions for dummy anchor tag.

    1. <a style="cursor: pointer;"></a>
    2. <a href="javascript:void(0)" ></a>
    3. <a href="current_screen_path"></a>

4.If you are using bootstrap:

<button class="btn btn-link p-0" type="button" style="cursor: pointer"(click)="doSomething()">MY Link</button>

There are ways of doing it with angular2, but I strongly disagree this is a bug. I'm not familiarized with angular1, but this seems like a really wrong behavior even though as you claim is useful in some cases, but clearly this should not be the default behavior of any framework.

Disagreements aside you can write a simple directive that grabs all your links and check for href's content and if the length of it it's 0 you execute preventDefault(), here's a little example.

@Directive({
  selector : '[href]',
  host : {
    '(click)' : 'preventDefault($event)'
  }
})
class MyInhertLink {
  @Input() href;
  preventDefault(event) {
    if(this.href.length == 0) event.preventDefault();
  }
}

You can make it to work across your application by adding this directive in PLATFORM_DIRECTIVES

bootstrap(App, [provide(PLATFORM_DIRECTIVES, {useValue: MyInhertLink, multi: true})]);

Here's a plnkr with an example working.


Updated for Angular2 RC4:

import {HostListener, Directive, Input} from '@angular/core';

@Directive({
    selector: '[href]'
})
export class PreventDefaultLinkDirective {

    @Input() href;
    @HostListener('click', ['$event']) onClick(event) {this.preventDefault(event);}

    private preventDefault(event) {
        if (this.href.length === 0 || this.href === '#') {
            event.preventDefault();
        }
    }
}

Using

bootstrap(App, [provide(PLATFORM_DIRECTIVES, {useValue: PreventDefaultLinkDirective, multi: true})]);

Here are some ways to do it:

  • <a href="" (click)="false">Click Me</a>

  • <a style="cursor: pointer;">Click Me</a>

  • <a href="javascript:void(0)">Click Me</a>


I wonder why no one is suggesting routerLink and routerLinkActive (Angular 7)

<a [routerLink]="[ '/resources' ]" routerLinkActive="currentUrl!='/resources'">

I removed the href and now using this. When using href, it was going to the base url or reloading the same route again.


I am using this workaround with css:

/*** Angular 2 link without href ***/
a:not([href]){
    cursor: pointer; 
    -webkit-user-select: none; 
    -moz-user-select: none; 
    user-select: none
}

html

<a [routerLink]="/">My link</a>

Hope this helps


simeyla solution:

<a href="#" (click)="foo(); false">
<a href="" (click)="false">

Updated for Angular 5

import { Directive, HostListener, Input } from '@angular/core';

@Directive({
  // tslint:disable-next-line:directive-selector
  selector : '[href]'
})
export class HrefDirective {
  @Input() public href: string | undefined;

  @HostListener('click', ['$event']) public onClick(event: Event): void {
    if (!this.href || this.href === '#' || (this.href && this.href.length === 0)) {
      event.preventDefault();
    }
  }
}

Examples related to angular

error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class error TS1086: An accessor cannot be declared in an ambient context in Angular 9 TS1086: An accessor cannot be declared in ambient context @angular/material/index.d.ts' is not a module Why powershell does not run Angular commands? error: This is probably not a problem with npm. There is likely additional logging output above Angular @ViewChild() error: Expected 2 arguments, but got 1 Schema validation failed with the following errors: Data path ".builders['app-shell']" should have required property 'class' Access blocked by CORS policy: Response to preflight request doesn't pass access control check origin 'http://localhost:4200' has been blocked by CORS policy in Angular7

Examples related to routing

Send data through routing paths in Angular Angular2 Routing with Hashtag to page anchor Passive Link in Angular 2 - <a href=""> equivalent laravel throwing MethodNotAllowedHttpException How to use absolute path in twig functions S3 Static Website Hosting Route All Paths to Index.html AngularJS - How can I do a redirect with a full page load? Web API Routing - api/{controller}/{action}/{id} "dysfunctions" api/{controller}/{id} The requested resource does not support HTTP method 'GET' My Routes are Returning a 404, How can I Fix Them?

Examples related to angular2-routing

'router-outlet' is not a known element How to reload page the page with pagination in Angular 2? Error: Cannot match any routes. URL Segment: - Angular 2 Can't bind to 'routerLink' since it isn't a known property Passing data into "router-outlet" child components How to determine previous page URL in Angular? How to get parameter on Angular2 route in Angular way? Angular 2 Scroll to top on Route Change Angular routerLink does not navigate to the corresponding component Angular 2 router.navigate

Examples related to angular-router

Angular 5 Scroll to top on every Route click Send data through routing paths in Angular Angular: How to update queryParams without changing route In Angular, What is 'pathmatch: full' and what effect does it have? How do I navigate to a parent route from a child route? Passive Link in Angular 2 - <a href=""> equivalent