intercept outgoing links Angular 4

Viewed 5324

so I write this small app where I show some information fetched from Wikipedia. There are also links inside of this fetched HTML.

So what I want to do:

Every time the user clicks on a link I want to intercept this and do custom behavior instead of the default browser redirect.

The build in Angular httpinterceptor is not working here. How do I get this effect?

EDIT: seems like I misunderstood how the href and http requests work. Still I want to do custom behaviour on every link clicked on my application. Is there no possible way to intercept those "events"?

EDIT: For a Angular 2+ Solution look into my answer below. Its a service for intercepting tags.

3 Answers

Okay after searching a little longer I found a "not angular" solution: Override default behaviour for link ('a') objects in Javascript

And so I created a service out of this and injected it in my App Root component.

import { Injectable } from '@angular/core';

@Injectable() export class HrefInterceptorService {

    constructor() {
        document.onclick = this.interceptHref;
    }

    interceptHref(_event) {
        const tEvent = _event || window.event;

        const element = tEvent.target || tEvent.srcElement;

        if (element.tagName === 'A') {

            console.log("intercept!");

            return false; // prevent default action and stop event propagation
        }
    } }

Its a little hacky but relatively flexible.

I needed to track outbound clicks for analytics purposes with pages that were built with [innerhtml] as well. I tried a bunch of things, but the answer turned out to be really simple. I only need to check a couple of levels up parents for the appropriate link element:

public hrefClicked( $event )
{
  let targetElement;

  if( ( $event.srcElement.nodeName.toUpperCase() === 'A') )
      targetElement = $event.srcElement;
  else if( $event.srcElement.parentElement.nodeName.toUpperCase() === 'A' )
      targetElement = $event.srcElement.parentElement;
  else
      return;

  //  console.log( "Found LINK:" );
  //  console.log( targetElement.href );

  if( targetElement.href && !targetElement.href.includes("mydomain"))
    {
     console.log( "OUTBOUND LINK:" + $event.srcElement.href );
    }
 }
<div class="container-fluid" (click)="hrefClicked($event)">
  <div class="row">
    <div class="col-xs-12">
      <div class="article-body" [innerHTML]="article.content"></div>
    </div>
  </div>
</div>  

Loading a new page is not an XHR request. So interceptors can't work. You need to capture the click event and prevent propagation:

template:

<a href="//example.com" (click)="myHandler($event)">Click me</a>

component:

myHandler(event){
  event.preventDefault();

  doSomethingElse();
}
Related