Search code examples
vue.jsvuejs2reactivevuetify.jsvue-chartjs

VueJs - Passing variables between methods


There is a v-select component and on change I am firing up fillData(selected) where selected is the v-model. And I need to update the label in datacollection.datasets.label on change. How do I do that ?

<script>
  import BarChart from './BarChart.js'
  import { mapGetters, mapActions } from "vuex";

  export default {
    name : "TestLegPerformance",
    components: {
      BarChart
    },
    data: () => ({   
      datacollection : {
          labels: ['Week-1','Week-2','Week-3'],
          datasets: [
            {
                label: '',
                backgroundColor: '#C58917',
                data: [40, 50, 20]
            }
          ]
        },
      selected: []

    }),
     computed: {
        ...mapGetters({
        planNames: "planNames"
        })
    },
    mounted () {
        this.getAllPlanNamesAction();
    },
    methods: {
      ...mapActions(["getAllPlanNamesAction"]), 
      fillData(selected){
          console.log(selected)
      },
    }
  }
</script>

Solution

  • Inside methods, you can reference to data properties using this.

    In your case, you can use this.datacollection.datasets.label and assign to it:

    methods: {
      // ...
      fillData(selected){
         this.datacollection.datasets[0].label = selected;
      },
    }
    

    Of course, this assuming that selected is the string you want to assign to the label.

    Note: the this will only work when you declare the methods using methodName() {} (as you are) or methodName: function (){.... So don't use arrow functions when declaring vue methods, they will mess up your this.


    Bind to events using @ (v-on) not : v-bind)

    Your template:

    <v-select label="Select a Plan" :items="planNames" v-model="selected" single-line max-height="auto" :change="fillData(selected)" required >
    

    To listen to the change event, don't use:

    :change="fillData(selected)"
    

    use

    @change="fillData"
    

    Don't send an argument (it will mess things up). v-select will send you one already.

    Notice the replacement of : with @.

    The first, : is an alias to v-bind. So :change="xyz" is the same as v-bind:change="xyz".

    The second, @ is an alias to v-on. So @change="xyz" is the same as v-on:change="xyz". which is what you want.

    See demo JSFiddle here.


    Updating label of vue-chartjs's BarChart automatically

    Even though you are

    The chart is not reflecting the changes (the label does not change) automatically.

    I noticed this happens because the chart only reacts to whole datacollection changes, not to inner properties (like label).

    So the solution is to:

    • "clone" datacollection
    • update the label of the clone
    • assign the clone to this.datacollection

    And the chart will react (the label change will be reflected).

    So, change your fillData method to the following:

    fillData(selected){
        let collectionClone = Object.assign({}, this.datacollection);
        collectionClone.datasets[0].label = selected;
        this.datacollection = collectionClone;
    },
    

    Check here a working DEMO CODESANDBOX of this solution (see the changeLabelAndReassign() method of BarChart.vue).