1

If the point of using this sytax: <div ng-controller="BuildingsCtrl as bc">is to avoid using $scope(and apparently it is), then how should I go about using $http?

That is, how could I re-write the following code to not use $scope?

angular.module('atlasAngularApp')
    .controller('BuildingsCtrl', function ($scope, $http) {
        this.awesomeThings = [
            'HTML5 Boilerplate',
            'AngularJS',
            'Karma'
        ];
        this.getBuildings = function () {
            $http.get('http://localhost:40602/api/1.0/buildings')
                .then(function successCallaback(response) {
             ======>    $scope.buildings = response.data;
                    }, function errorCallback(response) {
                        alert("Error");
                }
            );
       }
   });

To elaborate a little more,

<li ng-repeat="thing in bc.awesomeThings">
    {{ thing }}
</li>

Works fine with this.awesomeThings, so a view can use this, but the following doesn't work:

angular.module('atlasAngularApp')
    .controller('BuildingsCtrl', function ($http) {
        var self = this;
        this.getBuildings = function () {
            $http.get('http://localhost:40602/api/1.0/buildings')
                .then(function successCallaback(response) {
             ======>    self.buildings = response.data;
                    }, function errorCallback(response) {
                        alert("Error");
                }
            );
       }
   });

(notice the self.buildings bit.)

I've tried a number of variations along these lines theme, but nothing so far has worked. This question is similar, but I wasn't able to adapt it to my code.

I should probably add that I don't have anything against $scope, I'm just trying to do things the way yeoman-generated angular seems to approve of. I'd also like some explanation on why $scope could be considered a bad thing.

For completeness, here's my view. Maybe there's something wrong with it?

<div ng-controller="BuildingsCtrl as bc">
    <table ng-init="buildings = bc.getBuildings()">
        <tr ng-repeat="building in buildings">
            <td>{{ building.name }}</td>
            <td>{{ building.code }}</td>
            <td>{{ building.image }}</td>
        </tr>
    </table>
</div>

The code does work, so long as I use $scope

Community
  • 1
  • 1
crowhill
  • 2,398
  • 3
  • 26
  • 55

2 Answers2

1

You are creating ng-init="buildings = bc.getBuildings()" but not returning anything to bind to buildings instead you are assigning values to self.buildings which is this.buildings indirectly. So, your repeat with buildings was not working. Now when you assign to this.buildings bc.buildings is what you are actually referring to in view. So,

<tr ng-repeat="building in bc.buildings">

repeats your elements.

As for your answer to using $scope and this. There is no better explanation than here:'this' vs $scope in AngularJS controllers

Community
  • 1
  • 1
Sunil Lama
  • 4,531
  • 1
  • 18
  • 46
0

First of all, those kind of calls to a back end are not supposed to be done by the controller. You should make a service for that to get it for you.

Secondly, most of the time you see controllers like this:

angular.module('atlasAngularApp')
.controller('BuildingsCtrl', function ($scope, $http) {
    var vm = this;
    vm.awesomeThings = [
        'HTML5 Boilerplate',
        'AngularJS',
        'Karma'
    ];

    vm.getBuildings = getBuildings;



    function getBuildings() {
        $http.get('http://localhost:40602/api/1.0/buildings')
            .then(function successCallaback(response) {
                vm.buildings = response.data;
                }, function errorCallback(response) {
                    alert("Error");
            }
        );
   }
});

Like that you can loop over the buildings of vm in your html:

<li ng-repeat="building in bc.buildings">
   {{ building }}
</li>

A good resource to look at in terms of best practices is the styleguide of John Papa: https://github.com/johnpapa/angular-styleguide

  • I pasted in your controller and got the same result. There's data in the view if I use `$scope.buildings`, there's nothing if I use`vm.buildings`. The view is up top now too. Maybe there's something wrong with it? – crowhill Feb 27 '16 at 00:29