4

I am new to Angular, so i think i am making some silly mistake but still not being to get a hold of it. I have created a service to fetch some data, then i have injected the service in my controller.

Service -

  .service('getAllCompanies', ['$http', function ($http) {
    // AngularJS will instantiate a singleton by calling "new" on this function
    var url = "http://localhost:8000/companies/?page=";
    this.getCompanies = function(p) {
        return $http.get(url+p);
    };
  }]);

Controller -

.controller('CompaniesallCtrl', ['getAllCompanies', function (companiesService) {
    var pageNumber = 1;
    this.companiesNumber = "";
    companiesService.getCompanies(pageNumber)
        .then(function(response){
            console.log(response.data.count);
            this.companiesNumber = response.data.count;
        }, function(error) {
            console.log(error);
        })
  }]);

I am getting this error in the console -

TypeError: Cannot set property 'companiesNumber' of undefined
    at companiesall.js:17
    at processQueue (angular.js:16170)
    at angular.js:16186
    at Scope.$eval (angular.js:17444)
    at Scope.$digest (angular.js:17257)
    at Scope.$apply (angular.js:17552)
    at done (angular.js:11697)
    at completeRequest (angular.js:11903)
    at XMLHttpRequest.requestLoaded (angular.js:11836)

The console.log(response.data.count) gives the correct result, so I am confused why is it showing undefined. Please help!

doctorsherlock
  • 1,334
  • 4
  • 19
  • 41
  • 1
    var self = this; self.compainesNumber = ""; companiesService.getCompanies(pageNumber) .then(function(response){ self.companiesNumber = response.data.count; }); – Srinivas Paila Jul 09 '16 at 22:24

2 Answers2

2

I guess you are using strict mode? Then context inside of then callback is going to be global object but this is indeed undefined. Use arrow function that will preserve lexical scope (controller instance in this case):

companiesService.getCompanies(pageNumber)
    .then(response => {
        console.log(response.data.count);
        this.companiesNumber = response.data.count;
    }, function(error) {
        console.log(error);
    })

Or bind to correct context:

companiesService.getCompanies(pageNumber)
    .then(function(response) {
        console.log(response.data.count);
        this.companiesNumber = response.data.count;
    }.bind(this), function(error) {
        console.log(error);
    })
dfsq
  • 191,768
  • 25
  • 236
  • 258
2

You could also set your controller as a variable in the scope of the function.

Something like:

.controller('CompaniesallCtrl', ['getAllCompanies', function (companiesService) {
    var pageNumber = 1;
    var ctrl = this;
    ctrl.companiesNumber = "";
    companiesService.getCompanies(pageNumber)
        .then(function(response){
            console.log(response.data.count);
            ctrl.companiesNumber = response.data.count;
        }, function(error) {
           console.log(error);
        }) 
}]);
segFault
  • 3,887
  • 1
  • 19
  • 31