0

I'm able to change an array with the code below.

new Vue({
  el: '#app',
  data: {
    students: [
      {name: "derek"},
      {name: "frank"}
    ],
  },
  methods: {
    changeStudents: function() {
      this.students = [
        {name: "aa"},
        {name: "bb"}
      ];
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id="app">
  <button @click="changeStudents">Click Me</button>
  <p v-for="student in students">{{student.name}}</p>
</div>

But when I try to change the array while inside a Google Firebase method it doesn't work. For some reason it doesn't know this.students is available. this.students should be accessible from any method, at least I thought. Could this be a pointer issue or something like that?

new Vue({
  el: '#app',
  data: {
    students: [
      {name: "derek"},
      {name: "frank"}
    ],
  },
  methods: {
    changeStudents: function() {
      
      var newStudents = [];
      
      // Get the students from the database
      studentsCol.get().then(function(querySnapshot) {
        querySnapshot.forEach(function(doc) {
          var student = doc.data();
          newStudents.push(student);
          
          // line below doesn't work because it doesn't know this.students
          // this.students.push(student);
          }
        });
      });
      // doesn't work either
      this.students = newStudents;
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.4/vue.min.js"></script>

<div id="app">
  <button @click="changeStudents">Click Me</button>
  <p v-for="student in students">{{student.name}}</p>
</div>
tazboy
  • 1,685
  • 5
  • 23
  • 39

1 Answers1

0

Use arrow functions as they use the lexical scope of the parent, in this case the scope of the changeStudents function, thus "this" refers to the the component instance, and students data property is then available.

studentsCol.get().then((querySnapshot) => {
        querySnapshot.forEach((doc) => {
          var student = doc.data();
          newStudents.push(student);

          // line below doesn't work because it doesn't know this.students
          // this.students.push(student);
          }
        });
      });

The forEach loop sets its own context, and "this" is overridden then, arrow functions solve this. However, if you don't want to use arrow functions, you can pass a context to the forEach loop, like this:

array.forEach(function(param) {
  // code
}, this);
8bit
  • 597
  • 5
  • 10
  • Thank you so much for pointing this out. I thought arrow functions were just a shortcut. I have a lot of reading and learning to do. – tazboy Nov 08 '17 at 02:33