1

I am quite new with VueJS and I have been having trouble lately with some computed properties which do not update as I would like. I've done quite some research on Stack Overflow, Vue documentation and other ressources but i haven't found any solution yet.

The "app" is basic. I've got a parent component (Laundry) which has 3 child components (LaundryMachine). The idea is to have for each machine a button which displays its availability and updates the latter when clicked on.

In order to store the availability of all machines, I have a data in the parent component (availabilities) which is an array of booleans. Each element corresponds to a machine's availability.

When I click on the button, I know the array availibities updates correctly thanks to the console.log. However, for each machine, the computed property "available" does not update is I would want it to and I have no clue why.

Here is the code

Parent component:

<div id="machines">
  <laundry-machine
    name="AA"
    v-bind:machineNum="0"
    v-bind:availableArray="this.availabilities"
    v-on:change-avlb="editAvailabilities"
  ></laundry-machine>
  <laundry-machine
    name="BB"
    v-bind:machineNum="1"
    v-bind:availableArray="this.availabilities"
    v-on:change-avlb="editAvailabilities"
  ></laundry-machine>
  <laundry-machine
    name="CC"
    v-bind:machineNum="2"
    v-bind:availableArray="this.availabilities"
    v-on:change-avlb="editAvailabilities"
  ></laundry-machine>
  </div>
</div>
</template>

<script>
 import LaundryMachine from './LaundryMachine.vue';

 export default {
  name: 'Laundry',
  components: {
    'laundry-machine': LaundryMachine
  },
  data: function() {
   return {
    availabilities: [true, true, true]
  };
 },
 methods: {
  editAvailabilities(index) {
    this.availabilities[index] = !this.availabilities[index];
    console.log(this.availabilities);
  }
 }
 };
  </script>

Child component:

<template>
  <div class="about">
    <h2>{{ name }}</h2>
    <img src="../assets/washing_machine.png" /><br />
    <v-btn color="primary" v-on:click="changeAvailability">
      {{ this.availability }}</v-btn>
 </div>
</template>

<script>
  export default {
  name: 'LaundryMachine',
  props: {
  name: String,
  machineNum: Number,
  availableArray: Array
  },
  methods: {
    changeAvailability: function(event) {
      this.$emit('change-avlb', this.machineNum);
      console.log(this.availableArray);
      console.log('available' + this.available);
    }
  },
  computed: {
    available: function() {
      return this.availableArray[this.machineNum];
    },
    availability: function() {
      if (this.available) {
        return 'disponible';
      } else {
        return 'indisponible';
      }
   }
  }
 };
</script>

Anyway, thanks in advance !

1 Answer 1

2

Your problem comes not from the computed properties in the children, rather from the editAvailabilities method in the parent.

The problem is this line in particular:

this.availabilities[index] = !this.availabilities[index];

As you can read here, Vue has problems tracking changes when you modify an array by index.

Instead, you should do:

this.$set(this.availabilities, index, !this.availabilities[index]);

To switch the value at that index and let Vue track that change.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you so much !
Thanks ! That actually didn't work but i used instead: this.$set(this.availabilities, index, !this.availabilities[index]); And that works. I was focusing on this computed property but didn't think about the methods, thanks a lot !

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.