1

i'm trying to pass props from api call to a child a component but its not working atm, when i console log the data in my child it return a proxy object with the correct data. but i'm unable to use it inside the defaultData computed method in my child component where i want to used it

parent component

<template>
  <CRow>
    <CCol :md="6" class="mb-4">
      <CCard>
        <CCardHeader>Grafik Pie Hama</CCardHeader>
        <CCardBody><CChartPieExample :labels="labels"/></CCardBody>
      </CCard>
    </CCol>
  </CRow>
</template>

<script>
import * as Charts from './index.js'
import axios from 'axios'

export default {
  name: 'Charts',
  components: {
    ...Charts,
  },
  data() {
    return {
      labels: [],
    }
  },
  methods: {
    async getData() {
      let formdata = new FormData();
      formdata.append("work_location", "1");
      formdata.append("date_from", "2020-01-01");
      formdata.append("date_to", "2021-12-28");
      formdata.append("id_customer", "3");
      formdata.append("id_customer_location", "0");
      const headers = {
        'Authorization': '1cf34c57882bf600d69d9828ee639232KVpR0'
      }
      try {
        await axios.post("https://dev.cleancity.id/api/home/ListResultReportBinatang", formdata, {headers: headers}).then(res => {
          res.data.response.data.map((item) => {
            this.labels.push(item.name_animal)
          })
        });
        
      } catch (error) {
        console.log(error)
      }
    },
  },
  created() {
    this.getData()
  },
}
</script>

child component

<template>
  <CChartPie :data="defaultData"/>
</template>

<script>
import { CChartPie } from '@coreui/vue-chartjs'
export default {
  name: 'CChartPieExample',
  components: { CChartPie },
  props: ['labels'],

  computed: {
    
    defaultData() {
      
      return {
        labels: this.labels,
        datasets: [
          {
            backgroundColor: ['#41B883', '#E46651', '#00D8FF', '#DD1B16'],
            data: [40, 20, 80, 10],
          },
        ],
      }
    },
  },
  created() {
    // this return proxy object, but unable to use this above in defaultData
      console.log(this.labels)

  },
  
}
</script>

UPDATE: i've tried using the watch method to watch for change for my labels, now the labels showed up on initial load but after i refresh the page / move to another page the labels dissapeared

updated child component

<template>
  <CChartPie :data="defaultData"/>
</template>

<script>
import { CChartPie } from '@coreui/vue-chartjs'
export default {
  name: 'CChartPieExample',
  components: { CChartPie },
  props: ['labels', 'values'],
  data() {
    return {
      labelsLocal: this.labels,
    };
  },

  watch: {
    labels(val, oldVal) {
      console.log(val)
      if (val !== oldVal) this.labelsLocal = val
    }
  },

  computed: {
    defaultData() {
      
      return {
        labels: this.labelsLocal,
        datasets: [
          {
            backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850", "#734222", "#A52019", "#8A9597", "#DE4C8A", "#F44611", "#999950", "#C51D34", "#382C1E", "#CAC4B0", "#A2231D"],
            data: [40, 20, 80, 10, 10],
          },
        ],
      }
    },
  },

  mounted(){
    console.log(this.labels)
  },
  
}
</script>

1

2 Answers 2

0

You can use watch feature to update the default data.

export default {
    data(){
        return {
            defaultData: {
            }
        }
    }
    watch: {
        labels(newVal, oldVal) {
            this.defaultData = {
                labels: this.labels,
                datasets: [...]
            }
        }
    }
}
Sign up to request clarification or add additional context in comments.

2 Comments

does not work, how can i use the newVal and oldVal to update the labels?
you can just use this.labels. it is updated, or you can use newVal: {labels: newVal}
0

Did you tried to use vm.$watch API?

parent component:

data() {
  return {
    labels: [],
  }
},
methods: {
  async getData() {
     const payload = this.toFormData({
      work_location: '1',
      date_from: "2020-01-01",
      date_to: "2021-12-28",
      id_customer: "3",
      id_customer_location: "0"
    })
    const headers = {
      'Authorization': '1cf34c57882bf600d69d9828ee639232KVpR0'
    }
    try {
      await axios.post("https://dev.cleancity.id/api/home/ListResultReportBinatang", payload, {headers: headers}).then(res => {
        this.labels = res.data.response.data.map(item => item.name_animal)
      });
      
    } catch (error) {
      console.log(error)
    }
  },
  toFormData(rawParams) {
    const params = new FormData()
    if (!this.isObject(rawParams)) return params
  
    const keys = Object.keys(rawParams)
    keys.forEach(key => {
      rawParams[key] !== undefined && params.append(key, rawParams[key])
    })
  
    return params
  },
  isObject(obj) {
    return obj !== null && typeof obj === 'object'
  }
},
mounted() {
  this.getData()
},

child component

data() {
  return {
    defaultData: {
      labels: [],
      datasets: [
        {
          backgroundColor: ["#3e95cd", "#8e5ea2","#3cba9f","#e8c3b9","#c45850", "#734222", "#A52019", "#8A9597", "#DE4C8A", "#F44611", "#999950", "#C51D34", "#382C1E", "#CAC4B0", "#A2231D"],
          data: [40, 20, 80, 10, 10],
        },
      ],
    },
  };
},
mounted() {
  const unwatch = this.$watch('labels', function(val) {
    this.$set(this.defaultData, 'labels', val)
    unwatch()
  })
},

Comments

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.