Skip to main content
Ben Nadel at LaunchDarkly Lunch & Learn 2018 (New York, NY) with: Chelsie-Jean Fernandez
Ben Nadel at LaunchDarkly Lunch & Learn 2018 (New York, NY) with: Chelsie-Jean Fernandez

The "Post-Link" Function Is The "Link" Function In AngularJS Directives

By
Published in Comments (4)

In AngularJS, directives are both powerful and complicated. Understanding them is not a one-time thing; it's a process that requires iteration and experimentation. The documentation is great; but, it will only take you so far. One thing that I wanted to clarify, that I personally find confusing in the documentations, is the fact that the "post link" function and the "link" function are the same thing in AngularJS directives.

Run this demo in my JavaScript Demos project on GitHub.

In the first half of the Directive documentation, AngularJS makes many references to the linking function. Then, later on, it refers to a linking object that can contain both a pre-link and a post-link function. And, while it explains how the link timing works (in relation to the Document Object Model and the child directives), I feel like the documentation never clearly states that the generic "link function" in the first half is the same as the "post link" function in the latter half.

To demonstrate that this is true, I have created three directives that each use the same link function reference. One configures the directive using the link function; one configures the directive using the link object; and, one configures the directive using nothing but the function reference.

<!doctype html>
<html ng-app="Demo">
<head>
	<meta charset="utf-8" />

	<title>
		The "Post-Link" Function Is The "Link" Function In AngularJS Directives
	</title>
</head>
<body>

	<h1>
		The "Post-Link" Function Is The "Link" Function In AngularJS Directives
	</h1>

	<p
		bn-using-post-link
		bn-using-link
		bn-using-fn-only>

		Look at the console-output; I am logging the link-functions from within the
		AngularJS source-code.

	</p>


	<!-- Load scripts. -->
	<script type="text/javascript" src="./angular-modified-1.3.6.js"></script>
	<script type="text/javascript">

		// Create an application module for our demo.
		var app = angular.module( "Demo", [] );


		// -------------------------------------------------- //
		// -------------------------------------------------- //


		// This function will be a shared-link function. In one instance, it will be used
		// as the only link function; in another instance, it will be used as the "post"
		// link function in a pre/post linking configuration; and in a final instance, it
		// will be used as the *only* directive configuration.
		function sharedLinkFunction( scope, element, attributes ) {

			console.log( "Linked, like a boss!" );

		}


		// I use the shared-link function as the "post-link" function.
		app.directive(
			"bnUsingPostLink",
			function() {

				return({
					link: {
						pre: angular.noop,
						post: sharedLinkFunction
					},
					restrict: "A"
				});

			}
		);


		// I use the shared-link function as the "link" function.
		app.directive(
			"bnUsingLink",
			function() {

				return({
					link: sharedLinkFunction,
					restrict: "A"
				});

			}
		);


		// I use the shared-link function as the only directive configuration.
		app.directive(
			"bnUsingFnOnly",
			function() {

				return( sharedLinkFunction );

			}
		);

	</script>

</body>
</html>

What you can't see in this code above is that I have altered the AngularJS source code to log out the Pre and Post linking function references during the compilation phase. Specifically, I have added a console.log statement ot the addLinkFns() function:

function addLinkFns(pre, post, attrStart, attrEnd) {

	console.log( "addLinkFns[ arguments ]:", arguments );

	// ... rest of function here ...

}

As you can infer from the argument names, the first argument is the pre-link function and the second argument is the post-link function. Now, when we run the above code, we get the following console output:

The post-link function is the same as the link function in AngularJS directives.

As you can see, the shared linking function is always being passed-in as the second argument. This holds true whether we define a "link function" or a "link object" that provides a post-link function. That's because these functions are one-in-the-same. When we use a link "object", the only "new" functionality we get is the pre-link function.

Want to use code from this post? Check out the license.

Reader Comments

6 Comments

It might be worth noting that basically the `link` property is just a shorthand for when the `compile` function is empty (which is the majority of times). "Normally", the linking function(s) are specified as the return value of the `compile` function, which can be either a (post-link) function or an object with pre-link and post-link functions registered via `pre` and `post` properties.

From [the docs][1]:

**compile**
[...]
A compile function can have a return value which can be either a function or an object.

* returning a (post-link) function - is equivalent to registering the linking function via the link property of the config object when the compile function is empty.

* returning an object with function(s) registered via `pre` and `post` properties - allows you to control when a linking function should be called during the linking phase. See info about pre-linking and post-linking functions below.

**link**
This property is used only if the compile property is not defined.
[...]

[1]: https://docs.angularjs.org/api/ng/service/$compile#-compile-

15,848 Comments

@ExpertSystem,

For me, that's one of those head-scratching moments from time to time. Since most directives do *not* require a Compile() function, I will sometimes write this the first time I try to create a compile function:

return({
compile: compile,
link: link,
restrict: "A"
});

.... and then I'm like *why* won't my link function execute?!?! Then, finally, I'm like, "Oh yeah, I gotta return it from the compile function!".

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel