[Coding] AngularJS – $scope vs. this

Posted by Khatharsis on July 23, 2014

Before leaving on vacation, I powered my way through Code School’s AngularJS tutorial. (Okay, it wasn’t that long or tedious; I had three days left in a short, holiday week and it provided a good/productive distraction for an hour or less each day. It’s even free, so give it a shot yourself.) Since then, I’ve been reading other intros to AngularJS articles and I was directed to watch Dan Wahlin’s 60-ish minute intro to AngularJS. There was one difference that I picked up on: Code School used this while Wahlin used $scope in their controller. Essentially:

Code School style:

var app = angular.module('myApp', []);
app.controller('myController', function() {
	this.someProperty = 'foo';
});

Dan Wahlin style:

var app = angular.module('myApp', []);
app.controller('myController', function($scope) {
	$scope.someProperty = 'foo';
});

Rather than refer to these styles as Code School/Wahlin styles, I’ll use the more conventional this (Code School) and $scope (Wahlin) labels. I found that using this vs. $scope has other implications in the HTML code as well. Namely, giving an alias to a controller and using the alias later on only works if the this convention is used.

Consider the following HTML code:

<div ng-app='myApp' ng-controller='myController as ctrl'>
	<ul>
		<li ng-repeat='item in ctrl.items'>{{item.name}}</li>
	</ul>
</div>


The “controller as” alias convention only works if the this style is used to set up the myController object. The same syntax can be used with $scope style, but no list will be populated and what’s worse, no error in Firebug.

I stumbled on this observation purely by mistake while working on AngularJS-ing my blog front-end (still in progress). I started on the code not long after finishing up the Code School tutorial, then after watching Wahlin’s video, I revisited my code to incorporate the $scope variable after being further convinced that it was the better practice (this is also a thread on the Code School forums). There are many other threads on this topic alone. There are also similar topics on why the “controller as” syntax (and hence use of this over $scope) is preferred (primarily to keep track of nested controllers and more beginner-friendly).

In the end, though, you’re locked into a sub-ecosystem when you make your decision. If you don’t expect to be using nested controllers, then $scope is the way to go. If you expect to use deeply nested controllers, then this and “controller as” may be more beneficial. The point is to not mix the two, that is, if you’re using $scope, don’t use this in a controller.

Between controllers? I’m not so sure. I imagine it’s more of a headache to mix controllers using $scope with controllers using this, so again, it would be better to stick with one convention throughout the application. But, I can also see if some controllers were truly in their own category and not expected to interact at all with the other controllers, using a different convention might be viable (e.g., a family of controllers that were nested vs. a family of controllers that were all flat).

There are probably more details involving the differences between the two. One article mentioned that although they performed similarly, the “scope” implied using this was not exactly the same as $scope. There were also other quirks mentioned that I didn’t read into much detail as it’s beyond me with my current skill level.

Nonetheless, it was an interesting connection to make and not something I would be consciously aware of had I not had the perfect set up to discover it on my own. Unfortunately, it does reintroduce the manual tracking of JavaScript problems before Firebug came along and changed/helped development. Both Firebug and Chrome’s developer tools do not give any hints as to why data does not display if there is a mismatch between styles.