20

I'm developing a rails app with angular, and in the past, I had been using $scope to access variables and methods of the angular's controllers. After watching the Shaping up with Angular.js course at codeschool, I realized that the usage of this and the alias of controllers are a better way of accessing them.

Anyway, my app works fine with $scope but when I change to the "this" implementation, the laboratories var came empty...

I let some code here: html:

<div ng-controller="LaboratorioController as labCtrl">
          <tr ng-repeat="laboratorio in labCtrl.laboratorios" >
            <td>{{ laboratorio.nombre }}</td>
            <td>{{ laboratorio.razon_social }}</td>
            <td>{{ laboratorio.direccion }}</td>

angular code:

(function() {
    var app = angular.module('guiaV', []);
    app.controller('LaboratorioController', function( $http) {
      this.laboratorios = [];
      return $http.get('./laboratorios.json').success(function(data) {
        return this.laboratorios = data;
      });
    });
})();

any idea?

3
  • 2
    @Blackhole i have already seen that answer and doesnt help me... Commented Jun 4, 2014 at 14:40
  • So here is a good tip: use $scope. Really. Commented Jun 4, 2014 at 14:42
  • 3
    Having a similar question "title" as stackoverflow.com/questions/11605917/… doesn"t make it necessarily a duplicate ... fast reviewers should also read content. Commented Jun 4, 2014 at 14:54

2 Answers 2

9

The function you put into angular.controller is used as a constructor. JavaScript constructors that return nothing, implicitly return this. If a constructor returns another object, then this object is supposed to be the new object. e.g.:

function Class1() {
    this.prop = 'xxx';
}
var obj1 = new Class1();
console.log(obj1.prop); // prints 'xxx'

function Class2() {
    this.prop = 'xxx';
    return {
        hooray: 'yyy'
    };
}
var obj2 = new Class2();
console.log(obj2.prop); // prints undefined
console.log(obj2.hooray); // prints 'yyy'

Your controller returns an http promise (the return value of $http.get(...).success(...)), so angular believes that this (the http promise) is your actual controller (the thing it assigns to $scope.labCtrl).

No time to test it, hope I got it right.

Tiny example here

Sign up to request clarification or add additional context in comments.

Comments

4

You assigned a value to this.laboratorios inside a closure. Remember that its scope is separated from the outer scope. this applies to something completely different. This is why using $scope is more reliable (and readable, if you ask my personal opinion). You might want to bind the closure to a this value:

(function() {
    var app = angular.module('guiaV', []);
    app.controller('LaboratorioController', function( $http) {
      this.laboratorios = [];
      $http.get('./laboratorios.json').success(function(data) {
        return this.laboratorios = data;
      }.bind(this));
    });
})();

Alternatively, you can use a variable that will be available from both scopes:

(function() {
    var app = angular.module('guiaV', []);
    app.controller('LaboratorioController', function( $http) {
      this.laboratorios = [];
      var foo = this;
      $http.get('./laboratorios.json').success(function(data) {
        return foo.laboratorios = data;
      });
    });
})();

12 Comments

Really no. Inside a controller, this isn't $scope.
@Blackhole You are not helping. Really.
@nilsK What is unclear? this isn't $scope, and detailed explanations are in the link.
You decided to downvote my answer, nitpick in the comments and make a noise about the answer being a dupe instead of just pointing the complete answer. I decided to help as much as I could.
Blackhole we are part of stackoverflow to help other developers, if you dont want to, please delete your account. Thanks @mingos, thats the attitude that a community of developers looks for.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.