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

7
  • what exactly is your problem? is your buildings not being rendered on the view? Commented Feb 27, 2016 at 0:12
  • Yes. Nothing appears in the view Commented Feb 27, 2016 at 0:14
  • you are binding buildings and repeating awesomethings in the view.can you show code parts for the rewrite without the use of scope Commented Feb 27, 2016 at 0:15
  • 1
    try ng-repeat="building in bc.buildings" in view and see result. Commented Feb 27, 2016 at 0:32
  • Yep. That was it, which makes perfect sense, now that I look at it. Thanks! Commented Feb 27, 2016 at 0:37

2 Answers 2

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

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

Comments

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

1 Comment

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 usevm.buildings. The view is up top now too. Maybe there's something wrong with it?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.