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?

Nmk
  • 1,281
  • 2
  • 14
  • 25
jandresrodriguez
  • 794
  • 7
  • 18

2 Answers2

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

Kos Prov
  • 4,207
  • 1
  • 18
  • 14
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;
      });
    });
})();
mingos
  • 23,778
  • 12
  • 70
  • 107
  • 2
    [Really no](http://stackoverflow.com/questions/11605917/this-vs-scope-in-angularjs-controllers). Inside a controller, `this` isn't `$scope`. – Blackhole Jun 04 '14 at 14:40
  • 1
    @Blackhole You are not helping. Really. – nilsK Jun 04 '14 at 15:01
  • 1
    @nilsK What is unclear? `this` isn't `$scope`, and detailed explanations are in the link. – Blackhole Jun 04 '14 at 15:04
  • My dear insightful @Blackhole, please indicate where in my answer do I say that `this` and `$scope` are the same thing? I fail to see such an affirmation. – mingos Jun 04 '14 at 15:04
  • In your code: you're using `this.laboratorios`. Twice. – Blackhole Jun 04 '14 at 15:07
  • I think `return` before `$http.get ...` has to go and - as far as i understand - it will work fine – Kos Prov Jun 04 '14 at 15:22
  • No, I'm showing the OP how to assign a value to `this.laboratorios` inside a closure he used as the `$http` success callback. – mingos Jun 04 '14 at 15:22
  • @KosProv Yes, I missed that. I edited the answer to contain working code. Thank you for pointing this out. – mingos Jun 04 '14 at 15:23
  • @mingos. Yep. So you're solving only one of the two problems of the OP, right? – Blackhole Jun 04 '14 at 15:25
  • 2
    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. – mingos Jun 04 '14 at 15:31
  • 3
    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. – jandresrodriguez Jun 04 '14 at 15:39
  • you sir, are a master. Thanks a lot, you don't just resolve my error, you teach me the way and the difference. I flag this question in order to get back the erronous "duplicate". – Leandro Bardelli Aug 21 '14 at 20:50