Skip to main content
Ben Nadel at Scotch On The Rock (SOTR) 2010 (Brussels) with: Cyril Hanquez and Steven Peeters
Ben Nadel at Scotch On The Rock (SOTR) 2010 (Brussels) with: Cyril Hanquez Steven Peeters

ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3

By
Published in Comments (4)

This is a really minor post about a change in directive priority in AngularJS 1.3. The other day, in my post about using multiple templates in a single ngRepeat directive, Boris Litvinsky brought it to my attention that ngSwitchWhen now executes at a higher priority (1,200) than the ngRepeat directive (1,000). While it wasn't necessarily relevant to my previous post, it does mean that as of AngularJS 1.3, the ngSwitchWhen directive can now be used to conditionally link ngRepeat directives.

Run this demo in my JavaScript Demos project on GitHub.

Prior to AngularJS 1.3, the ngSwitchWhen directive used to execute at priority 800. This means that if you used it on the same element as ngRepeat (priority 1,000), it would transclude the element after ngRepeat had cloned it. It would then attempt to link the second clone in the context of ngSwitch, which is absolutely not what the developer was intending.

As of AngularJS 1.3, the ngSwitchWhen directive executes at priority 1,200 which means that it executes before ngRepeat. As such, the ngSwitchWhen directive can now work in conjunction with the ngSwitch directive to conditionally include an ngRepeat block:

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

	<title>
		ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3
	</title>
</head>
<body ng-controller="AppController">

	<h1>
		ngSwitchWhen Priority Is Higher Than ngRepeat Priority In AngularJS 1.3
	</h1>

	<h2>
		Friends
	</h2>

	<ul ng-switch="!! friends">

		<!-- Data is still loading. -->
		<li ng-switch-when="false">

			<em>Loading data...</em>

		</li>

		<!--
			Data has loaded and is ready to render.
			--
			As of AngularJS 1.3, ngSwitchWhen has a priority of 1,200, which is higher
			than ngRepeat (which has priority 1,000). As such, the ngSwitchWhen will
			determine whether or not the LI element is ultimately linked. Then, once it's
			linked, the ngRepeat directive will determine if it's repeatedly cloned.

			PRIOR to AngularJS 1.3, the ngSwitchWhen would have linked AFTER the
			ngRepeat. However, since it transcludes its content and then gets it linked
			in the context of the ngSwitch Scope, you end up bypassing the ngRepeat
			scope for the second transclusion... which is only PART of what makes double-
			transclusion a difficult use-case (in this case).
		-->
		<li
			ng-switch-when="true"
			ng-repeat="friend in friends">

			{{ friend.name }}

		</li>
	</div>


	<!-- Load scripts. -->
	<script type="text/javascript" src="../../vendor/angularjs/angular-1.3.8.min.js"></script>
	<script type="text/javascript">

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


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


		// I control the root of the application.
		app.controller(
			"AppController",
			function( $scope, $timeout ) {

				$scope.friends = null;


				// Defer the definition of the data so that we can simulate a loading
				// state while data "comes over the wire."
				$timeout(
					function deferLoading() {

						$scope.friends = [
							{
								id: 1,
								name: "Sarah"
							},
							{
								id: 2,
								name: "Tricia"
							},
							{
								id: 3,
								name: "Kim"
							}
						];

					},
					( 2 * 1000 )
				);

			}
		);

	</script>

</body>
</html>

Personally, I've never run into this limitation (and I'm still on AngularJS 1.0.8 in production). I've never needed to put ngSwitchWhen and ngRepeat on the same element. Typically, I would put ngSwitchWhen on a container and then have the ngRepeat as part of the descendant content. That said, I'm sure there are use-cases where this is a valuable change. And, it's good to see the AngularJS team continually refining and optimizing their directives.

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

Reader Comments

15,848 Comments

@André,

Very cool! One thing, though - I believe that ngSwitch is actually at priority:0. It's only the ngSwitchWhen / ngSwitchDefault that is now at priority:1,200.

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