0

I'm having some problems using this in VUE single file components (or any component for that matter).

This is probably not VUE specific issue (more javascript), but I've ran into it, while creating a VUE application.

In VUEJS this keyword is used inside single vue component to refer to the component itself. But if scope is changed (e.g. forEach loop), this no longer refers to the component but (as in example), this refers to the array being iterated.

One solution to this is to save this value first (e.g. var self = this;).

Example (not working):

<script>
  export default {
    data() {
      return {
        someProp: "stringValue",
        myArray: [
          { "key": "key1", "selected": true },
          { "key": "key2", "selected": true },
          { "key": "key3", "selected": true }
        ]
      }
    },
    methods: {
      method1: function() {
        var selectedKey = "";
        this.myArray.forEach(function(item) {
          // Obviously, accessing "this.someProp" here will not work
        });
      }
    }
  }
</script>

Example (working):

<script>
  export default {
    data() {
      return {
        myArray: [
          { "key": "key1", "selected": true },
          { "key": "key2", "selected": true },
          { "key": "key3", "selected": true }
        ]
      }
    },
    methods: {
      method1: function() {
        var self = this; // Save "this" reference
        var selectedKey = "";
        self.myArray.forEach(function(item) {
          // Here, accessing "self.someProp" will work since "this" was saved first.
        });
      }
    }
  }
</script>

My question is, is it possible to somehow specify "var self = this;" for all methods used in a component, without specifying it in each and every method? Somewhere on the start maybe? Probably cannot do it inside data function since it requires this modifier to be accessed.

Of course this is just a simple example, it could get more complex if, for example, calling some 3rd party libraries and providing them some callback functions where scope would be changed also.

Jure
  • 1,101
  • 5
  • 13
  • Not exactly, since it explains how "this" works, which I'm somewhat familiar with. My question was more of how to set variable in vue.js to value of "this" to be used in every method. I should rewrite my question somewhat differently. – Jure Jan 25 '20 at 16:35
  • Not entirely familiar, I'd say, at least the concept of contexts. Dupe questions answer that if you read them carefully. TL;DR: use an arrow, as the answer suggests. As for Vue, it already binds *methods* to correct `this`, there's nothing else to do. What you have inside forEach callback is not *method* context, hence the problem. *it could get more complex if, for example, calling some 3rd party libraries and providing them some callback functions where scope would be changed also* - if you have specific problem with 3rd party, consider asking a new question, it could be a different case. – Estus Flask Jan 25 '20 at 16:55
  • Arrow functions will do for now, so I will post another question if more complex issue should arise regarding accessing "this". – Jure Jan 25 '20 at 17:02

2 Answers2

3

Your foreach was not an arrow function that's why you can't call this inside of it. change all of your foreach to access this inside of it.

this.myArray.forEach(item => {
      // Here, you can use `this` already
 });
Qonvex620
  • 3,404
  • 1
  • 4
  • 14
  • This works, but it was a simple example. What is I call some 3rd party library which internaly does not use arrow functions and I must provide some kind of callback function? Although, for my case, this should be enough (for now). – Jure Jan 25 '20 at 16:29
  • instead of callback just use async function, anyways if this answer helped your, please mark it is an accepted answer. Thanks – Qonvex620 Jan 25 '20 at 16:31
1

Use arrow function to maintain your context.

this.myArray.forEach((item, index) => {
   // Do here your stuff, without calling self, just "this"
});

Regards

Ignacio
  • 126
  • 4