Search code examples
javascriptvue.jsvue-componentvuexvuex-modules

Pass a state of vuex to a chart - vue


I'm doing a chart component that will be several times represented on a page.

For that, I'm using Vuex where I have the mutations / actions to get that date, and everything works fine.

In the graph component, in created () I call the action to make the request, and I want to pass the date to the chart.

The state comes as follows -

{
   typeChart: [data],
   typeChart2: [data2]
}

If I do console.log from the state it appears fine but if using the key returns undefined.

console.log(this.dataChart)
// log - { stacked: Array }

console.log(this.dataChart.stacked);
//  log - undefined

The only way I found to pass the state to the chart was to do a timeout but I think that is not the best way to do this.

here's the code I have

component of page -

<template>
    <stacked-chart
        endpoint="endpoint"
        chart="stacked"
        :states="['state1', 'state2', 'state3']"
        :keys="['key1', 'key2', 'key3']"
    />
</template>

component of chart -

<template>
    <div class="box-content-white">
        <div class="title"> Gráfico 1 </div> <!-- //! name for chart -->
        <column-chart  :data="data" :stacked="true" :colors="['#006837', '#FF0000', '#000']"></column-chart>
    </div>
</template>

<script>
    import { mapGetters } from 'vuex';
    import { mapActions } from 'vuex';

    export default {
        props: {
            endpoint: String,
            chart: String,
            states: Array,
            keys: Array
        },
        data() {
            return {
                 data: []
            }
        },
        created() {
            this.fetchReporting({endpoint: this.endpoint, chart: this.chart, states: this.states, keys: this.keys, formData: { state: 'negotiation' }});
            console.log(this.dataChart);
            console.log(this.dataChart[this.chart]);
            setTimeout(() =>{
                this.data = this.dataChart[this.chart];
            }, 150);
        },
        methods: {
            ...mapActions({
                fetchReporting: 'fetchReporting'
            })
        },
        mounted() {

            this.data = this.dataChart[this.chart];
        },
        computed: {
            ...mapGetters({
                dataChart: 'dataChart'
            })
        },
        watch: {

        }
    }
</script>

file with vuex -

import axios from 'axios';

const state = {
    dataChart: {}
}

const mutations = {
    'ADD_DATA_CHART'(state, data) {
        state.dataChart[data.key] = [];

        [].forEach.call(data.states, (s, i) => {
            let obj = {};
            obj.name = s;
            obj.data = [];

            [].forEach.call(data.value, d => {
                obj.data.push([d.name, d[data.keys[i]].toFixed(2)]);
            });
            state.dataChart[data.key].push(obj);
        });
    }
}

const actions = {
    fetchReporting({state, commit}, response) {
        axios.post(response.endpoint, response.formData)
            .then(({data}) => {
                commit('ADD_DATA_CHART', {key: response.chart, value: data, states: response.states, keys: response.keys})
            }).catch(err => {
                console.log(err);
            });
    }
}

const getters = {
    dataChart: state => {
        return state.dataChart;
    }
}


export default {
    state,
    mutations,
    actions,
    getters
}

any suggestion?


Solution

  • You need to wait for you action fetchReporting to complete. Either by using async/await or by using promise/resolve