[Vuejs]-When using Vue methods I cannot use "this" when accessing data

4đź‘Ť

âś…

Here’s three approaches, with most modern going first:

loadGroups(){
    axios.get('/api/groups')
        .then(response => {   // for arrow functions `this` is just another variable
            // handle success
            this.groups = response.data;
        });
}

loadGroups(){
    axios.get('/api/groups')
        .then(function (response) {
            // handle success
            this.groups = response.data;
        }.bind(this));     // binding `this` to the function makes it keep `this`
}

loadGroups(){
    var that = this;        // old style approach with a proxy variable
    axios.get('/api/groups')
        .then(function (response) {
            // handle success
            that.groups = response.data;
        });
}

The reason your this is getting lost is that the callback is not called as a method. A method call happens when the function is defined with function keyword (not an arrow) and you call it from a property on an object (i.e. there is a dot somewhere – or at least square brackets). The object is called “receiver”, and is assigned to this.

const obj = {
  not_method: x => x * 2,
  method: function(x) { return x*2; }
}
obj.not_method()    // not a method call (arrow); `this` is unaffected
f = obj.method; f() // not a method call (not property); `this` is `global` or `window`
obj.method()        // method call; `this` is `obj`
obj['method']()     // still a method call; `this` is obj

axios.get doesn’t care about this; it receives a parameter, e.g. as callback, and calls it: callback(response); as there’s no dots or square brackets in callback, it’s not a method call, and this is the global scope.

The first piece of code changes the function into an arrow function. Arrow functions, by their definition, completely ignore this, treating it as any other variable. Thus, this will be closed over by the function, and you can access it from the closure for the value it had outside the closure.

The second piece of code uses Function.prototype.bind to force a function to assign this to a value of our choosing. It can also fill some of the parameters, but we are not using it for that, just the receiver.

The third piece of code simulates the first one, before arrow functions were a thing. We assign the value of this to another variable, which is not magic like this, and will thus be captured in the closure by the normal mechanism.

👤Amadan

Leave a comment