Flame_Phoenix Flame_Phoenix - 4 years ago 168
AngularJS Question

Why is $scope not working in Angular 1.6.1?

Background



After following the AngularJS tutorial on codeSchool and reading some StackOverflow questions, I decided to start using
$scope
in order to avoid the hassle of having to define a
var self = this;
variable.

Problem



The problem is that
$scope
seems to not be binding anything and nothing works when I use it. I have no idea why, but if I use a
var self = this;
variable my code will work, even though in theory (according to what I know)
$scope
should do the same ...

Code



Let's say I have a page where I want to display a big list of numbers. Let's also say I have pagination, and that I want the default amount of Numbers per page to be 4. Let's also assume that after each request to the server, I set the amount of Numbers shown per page to 4 again.

app.js

/*global angular, $http*/

(function() {
var app = angular.module("myNumbers", []);

app.directive("numberFilter", function() {
return {
restrict: "E",
templateUrl: "number-filter.html",
controller: function($scope, $http) {
$scope.filter = {
itemsPerPage: 4
};

$scope.makeRequest = function(numberList) {
console.log("Received submit order");

$http({
method: 'GET',
url: 'https://myNumberServer.com/api/v1/getPrimes',
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}).then(function successCallback(response) {
numberList= response.data.entries;
$scope.totalPages = response.data.totalPages;
$scope.filter = {itemsPerPage: 4};
console.log("success!");
}, function errorCallback(response) {
console.log('Error: ' + response);
});
};
},
controllerAs: "filterCtrl"
};
});
})();


number-filter.html

<form ng-submit="filterCtrl.makeRequest(myNumbers.numberList)">
<div >
<label for="items_per_page-input">Items per page</label>
<input type="number" id="items_per_page-input" ng-model="filterCtrl.filter.itemsPerPage">
</div>

<div>
<button type="submit">Submit</button>
</div>
</form>


There are two expected behaviors that should happen and don't:


  1. When I click submit, I should see in the console
    "Received submit order"
    and I don't.

  2. The
    input
    element should be initialized with 4 when I load the page.



Both of these behaviors will happen if I use the
var self = this;
trick and replace all mentions of
$scope
with
self
.

Questions:


  1. Why is this not working? Am I missing some closure?


Answer Source

You are using controllerAs syntax so when you use that your model needs to be assigned to the controller object itself, not to $scope

Example

controller: function($scope, $http) {

  var vm = this; // always store reference of "this"

  // use that reference instead of $scope
  vm.filter = {
    itemsPerPage: 4
  };

  vm.makeRequest = function(numberList) {
    console.log("Received submit order");

    $http({
      method: 'GET',
      url: 'https://myNumberServer.com/api/v1/getPrimes',
      headers: {
        'Content-Type': 'application/json; charset=utf-8'
      }
    }).then(function successCallback(response) {
      numberList = response.data.entries;
      vm.totalPages = response.data.totalPages;
      vm.filter = {
        itemsPerPage: 4
      };
      console.log("success!");
    }, function errorCallback(response) {
      console.log('Error: ' + response);
    });
  };
},
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download