Build a Debug Directive

John Lindquist
InstructorJohn Lindquist
Share this video with your friends

Social Share Links

Send Tweet
Published 10 years ago
Updated 5 years ago

Explore some interesting techniques with AngularJS directives to create a debug directive using termination, priority, and the $compile service.

John Lindquist: When you're writing your angular code all you get to see is the output in the browser you don't get to see the original expressions that were used to create that output.

If you want to see those you can use something call "ng-non-bindable" so that when I refresh here I can see the original expressions but now I don't get to see the final output. For debugging purposes maybe that would be a fun thing to see just to see what it originally was and then what the actual output is so you can compare and make sure everything's working just fine.

Let's set up a debug directive. I'm just going to create it there before I even start making it. So, egghead and directive, and we'll just say debug. From here we'll return our object. The first thing we'll do is say terminal, true. This basically means, "Don't run any other directives, stop here," and this will achieve that same result.

You can see that if I delete this and I refresh that it renders. But when I say terminal that means, "Don't do anything after this directive, just stop here." I'm also going to set a priority to something super high. This hasn't actually conflicted with anything I have seen but maybe it might for you. This just means, "Run this directive before any others run." We'll say, "Run it first, stop everything else."

What we can do now in our link function we can get our original scope, our original element and from there use those to compile it. We're going to clone the original element because we want to keep that original element there. We'll say "clone," we'll grab the clone. Then with the clone we'll need to remove the attribute of debug. This is super important or else you will crash your browser.

It crashes Chrome all the time if you do this because in the next step when you compile, which means we'll have inject the compiler. When we compile this, I'll compile our clone and I'll pass in the scope is the other thing you need for compiling. I get the cloned element and I just append it or add after the current element.

We'll say "clone to element." I hit refresh here you can see I get the original uncompiled element and then I get a compiled element, which is returned here and then added after the original element.

If you weren't to remove this attribute then this would crash the browser. You can try that on your own. I'm not going to do that right now.

One other thing I just want to do is just for debugging purposes I'll just say something like add an attribute of style, there's a million ways to do this, and we'll just say color red. I can see that this is obviously my debug stuff and then is not debug stuff.

I can just take this directive, I can add it anywhere I want. I want to debug this as well, two plus two is four and I can see that two plus two comes out to four.

This is a fun way of just building debugging tools to see what your element is before and what it is after it's compiled. Then once it's done you can actually just remove this directive all together or you could set up a service that would toggle true-false if you were in debug mode, however you want to achieve that.

But once you have that you can do whatever manipulation to this you'd want to see what's going on before and after the angular expressions have executed.

Marty
Marty
~ 9 years ago

This is a question that I derived from the video but it is off topic.

In the video scope and element had to be passed (injected) into the linking function so they could used. Then the $compile had to be passed (injected) into the directive so it could be used.

Sometimes functionality is injected directly into the link function and sometimes it's injected into the directive.

What is the difference between functionality passed into the linking function and functionality passed into the directive?

John Lindquist
John Lindquistinstructor
~ 9 years ago

The directive uses angular's injection (you can inject services, etc).

The link function only takes arguments (scope, element, attrs, ctrl, transclude) which can't be changed. You can't inject services, etc into the link function since angular always calls it with those arguments.

Marty
Marty
~ 9 years ago

Thanks John.

Markdown supported.
Become a member to join the discussionEnroll Today