0

I have the following controller and http request.

I'm setting connectionError to false and want to set it to true on the callbackError in the http request.

I get the following error when using this

Cannot set property 'connectionError' of undefined

Everything works fine when I use $scope.

I've read the following article https://toddmotto.com/digging-into-angulars-controller-as-syntax/ which explains a lot about this and scope and kind of understand that in my code below the this that initially sets 'connectionError' to false is not the same this within the callbackError function as this refers to the function it resides in...?!? (well that's currently what I'm interpreting...)

So my question is - is there a way to set the 'connectionError' to true. Or is this a classic example where $scope is better suited?

Code:

var userApp = angular.module('UserApp', []);


userApp.controller('UserListCtrl', ['$scope', '$http', function ($scope, $http){

    var type = this;
    type.users = [];

    // doesn't work
    this.connectionError = false;
    // works
    $scope.connectionError = false;

    // get the data
    $http.get('./types/users.json')
        // on success
        .then(function successCallback(response){
            type.users = response.data;

        },
        // on error
        function errorCallback(response){
            // doesn't work
            this.connectionError = true;
            // works
            $scope.connectionError = true;
        });

}]);
fidev
  • 1,222
  • 2
  • 21
  • 51

2 Answers2

1

You get the error because this has a different value when used inside another function.

To use this of the controller function inside the error callback assign this to another variable in the controller. In this case you already did it with type variable so use it!

        function errorCallback(response){
            type.connectionError = true;
        });    

And regarding $scope, especially if you are using controllerAs syntax, strongly avoid it.

pietrovismara
  • 6,102
  • 5
  • 33
  • 45
  • Thanks. Can't believe I didn't see that, and I'm already using it in the callbackSuccess function.... :0 Too many hours staring at code.....! – fidev Mar 13 '16 at 14:22
  • 1
    I know i know man :) `this` usage in javascript is one of the most confusing things i stumbled upon, so i suggest you to open the console and make some experiment with it until you understand properly how it works. Also, take a look at ES6 fat arrow functions, which solve this problem. – pietrovismara Mar 13 '16 at 14:24
1

The context this in the error handler is not the one from main controller function. In strict mode, the context of a function invocation is undefined.
To solve this and have access to controller's this, use the bind() method:

$http.get('./types/users.json')
    // on success
    .then(function successCallback(response){
        type.users = response.data;

    },
    // on error
    function errorCallback(response){
        // Now will work
        this.connectionError = true;
        // works
        $scope.connectionError = true;
    }.bind(this));

See more details in Gentle explanation of this.

Dmitri Pavlutin
  • 18,122
  • 8
  • 37
  • 41