Dismiss
Announcing Stack Overflow Documentation

We started with Q&A. Technical documentation is next, and we need your help.

Whether you're a beginner or an experienced developer, you can contribute.

Sign up and start helping → Learn more about Documentation →

Cannot Use ControllerAs this

Can anyone explain the following scenario to me, please?

Works

ng-controller="Parent as thus"

Breaks

ng-controller="Parent as this"

That single letter which makes it a keyword -- which I want -- wrecks the forest.

Why is this?

P.S. I'm aware of the vm convention, but I find it disturbs portability of controllers/viewmodels.

share|improve this question
2  
but I find it disturbs portability of controllers/viewmodels ? can you please explain "this"? no pun intended – Parv Sharma Jul 11 at 20:23
2  
I'm guessing Angular tries to evaluate that passed in string, and this is a reserved word. – tymeJV Jul 11 at 20:23
    
In terms of architecture, its a bad practice to couple to your base-lib/framework. As so, you may want to port your generic Viewmodel from system to system. I find the vm approach to incur some degree of change-cost when ports occur. For instance, if I took a generic CalendarViewmodel that is used for all projects, I would have to go through all references of this and turn it into vm; just for that controller. That's the oversimplified example, and its just one of many. A lot more to be said here. – Cody Jul 11 at 20:32
up vote 2 down vote accepted

The problem is certainly not that this is a reserved word in JavaScript. There is no rule in the controller as syntax that says you would need to assign the value of this to a variable with the same name as the controller and I'm pertty sure angular won't do such thing either. Why would it? That would be incredibly stupid use of Function constructor and just a needless bug.

There's a simple way to test that JavaScript reserved words are not the issue here. Name your controller "throw". "Parent as throw". throw is a reserved word, but does that throw errors? No. Does that work? Yes.

this is, however, reserved in the context of angular's own template expressions. It's used to refer to the current scope of the expression.

<div ng-controller="Parent as this">
    {{log(this)}}
</div>


angular.module('testApp', []).controller('Parent', function($scope){
    this.test = 'foo';
    $scope.log = function(arg){
        console.log(arg);
    };
});

The above won't throw errors, but it won't log the controller either. Instead, it will log a scope object containing the log function and $parent and what not.

In fact, it will also contain something intresting to us: property this: Object, our controller.

And sure enough, change the template expression to {{log(this.this)}} and it will log the controller instance just fine. Still wouldn't use 'this' as the name though, it would probably just cause more bugs by mistake than undefined functions ever have.

share|improve this answer
    
While this is certainly MORE informative, it still doesn't give a definitive answer as to why AngularJS is refusing to parse the keyword. – David L Jul 11 at 21:03
    
Ahh! What a beautiful answer. Thanks [big time] for the help. – Cody Jul 11 at 21:04
    
@DavidL What makes you think angular doesn't parse it? In the example above, angular certainly parses the "Parent as this" expression. It just refuses to override the value of word this in the template scope. There could be many reasons for that, from design decisions to implementation details. Or are you experiencing actual errors that I just don't know about? – noppa Jul 11 at 21:06
    
"this is, however, reserved in the context of angular's own template expressions". What I'm saying is that this claim would be ideally backed up with the source that demonstrates this. The filter is obviously applied somewhere in the expression syntax and the source for it would be wonderful. Your explanation otherwise is perfectly sound. – David L Jul 11 at 21:10
1  
@noppa, I think you're referring to my last sentence there, but that's just wishful thinking. I think they're doing it the best way, actually, in order to encapsulate what varies. I think you still need to have the scope/prototype chain, which probably necessitates having this as the markup's context. I think we totally agree ;) – Cody Jul 11 at 21:31

You are cannot use this as the instance name. this is a reserved keyword.

It would be the equivalent of doing:

var this = new Controller();

You can see that is wrong. It should be something like:

var ctrl = new Controller();

This is essentially what angularJs does behind the scenes when you do controllerAs="Controller as ctrl"

share|improve this answer
1  
Well, I would think what Angular is doing is more like var hash = {}; hash['this'] = new Controller(); -- which is totally legal syntax. You can indeed have an instance variable referenced as this.this. – Cody Jul 11 at 20:37

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.