Write a post

Enjoy this post? Give Mason Hargrove a like if it's helpful.

AngularJS Tip: How to Fix an Angular Directive Issue

Published Aug 13, 2015Last updated Feb 09, 2017

What do I do if I find something wrong with one of Angular's directives?

I recently found myself in a jam when using ng-touch on an angular app I have been working on. My app relies on SEO heavily so I must ensure most of my anchor elements have href attributes with url's assigned to them. On a few of the anchor elements I have also had to attach an ng-click to the element to run a function in my controller. This poses a problem for ng-touch.

If any anchor element in your codebase has an ng-click and an href attribute attached angular ignores your url and runs the ng-click as expected.

Here's an example of my anchor element

<a href="/some/url" ng-click="myControllerFunction()"></a>

One option I could do to solve my dilemma is to move the location change into the function inside my controller like so.

//Save my url to navigate to on click
var url = '/some/url';

$scope.myControllerFunction = function() {
  $location.path(url);
};

This functionality would work except I would have to manually find every anchor element that had both an href and an ng-click attached to it inside my codebase. This proved extremely difficult due to the fact that there was no real way to search for that inside of my text editor and there are thousands of anchor elements in my application.

Where my trick comes into play

I recently learned that if you create 2 directives with the same name that BOTH of the directives will be applied to the element. Here's an example.

To fix my issue I created a new ngClick directive that conditionally checked if the element had an href attached and if so navigate to the url provided, if not continue like normal. It looked like this:

angular.module('ngClick', function( $location ) {
  return {
    link: function(scope, elem, attrs) {
      if(attrs.href) {
        elem.on('touchend', function() {
          $location.path(attrs.href);        
        });
      }
    },
    priority: 1
  };
});

I attached an event to listen for the touchend only if an href attribute is present on the element in the DOM. I also gave it a higher priority than the native ng-click to change my location before the native ng-click function is ran.

Why is this useful?

This is not a very common issue most developers are going to run into but doing this trick allowed me to fix my issue without having to even look for the elements in my codebase! I have never seen any documentation on creating new directives this way and I hope it could save you some time in the future.

Please comment and let me know if you could have benefited from knowing any of this.

Thanks!

Discover and read more posts from Mason Hargrove
get started
Enjoy this post?

Leave a like and comment for Mason

2Replies
Karl Gjertsen
a year ago

Thanks for this article.I found it as I was searching for an answer to the same problem you had.

Raj
2 years ago

Angular tutorial step by step

http://dotnetlearners.com/t…

Subscribe to our weekly newsletter