user6740794
user6740794

Reputation:

Vue: Error in created hook: "TypeError: Cannot convert undefined or null to object"

So when I try to run my parent component 'Dashboard' in my browser. The child component 'ChartUsage' throws an error in my console: [Vue warn]: Error in created hook: "TypeError: Cannot convert undefined or null to object" When I try to debug I see that the prop: userSubmitsProp, just return an empty array. So that's also strange. But I can't figure out why. Can anyone help me out?

Parent component that send the prop: userSubmitsProp:

<template>
  <div class="dashboard">
    <cards :userDataProp="currentUserData"/>
    <chartusage :userSubmitsProp="previousSubmits" />
  </div>
</template>

<script>
import db from '@/firebase/init'
import firebase from 'firebase'
import moment from 'moment'
import Chartusage from '@/components/dashboard/ChartUsage'
import Cards from '@/components/dashboard/Cards'

export default {
  name: 'Dashboard',
  components: {
    Chartusage,
    Cards
  },
  data () {
    return {
      currentUserData: {},
      previousSubmits: []
    }
  },
  created () {
    let user = firebase.auth().currentUser

    // find the user record
    db.collection('users').where('user_id', '==', user.uid).get()
      .then(snapshot => {
        snapshot.forEach((doc) => {
          let userData = doc.data()
          userData.timestamp = moment(doc.data().timestamp).format('lll')
          this.currentUserData = userData
        })
      })
      .then(() => {
        // fetch the user previous submits from the firestore
        db.collection('submits').where('user', '==', this.currentUserData.alias).get()
          .then(snapshot => {
            snapshot.forEach(doc => {
              let submit = doc.data()
              submit.id = doc.id
              submit.timestamp = moment(doc.data().timestamp).format('lll')
              this.previousSubmits.push(submit)

              // sort previousSubmits array by date
              this.previousSubmits.sort((a, b) => {
                a = new Date(a.timestamp)
                b = new Date(b.timestamp)
                return b - a
              })
              console.log(this.previousSubmits)
            })
          })
      })
  }
}
</script>

<style>
</style>

Child component that receives the userSubmitsProp prop to make a chart with it:

<template>
  <div class="check-usage">
    <div class="row">
      <div class="col s12">
        <div class="chart">
          <chartjs-line
            :fill="true"
            :datalabel="'My household usage'"
            :labels="labels"
            :data="dataset"
            :bordercolor="'#1976D2'"
            :backgroundcolor="'rgba(25,118,210, 0.5)'"
            :pointborderwidth="mywidth"
            :pointbordercolor="mypointbordercolor"
            :pointhoverborderwidth="hoverwidth"
            :pointhoverbackgroundcolor="hoverbackgroundcolor"
            :pointhoverbordercolor="hoverbordercolor"
            :bind="true">
          </chartjs-line>
          </div>
      </div>
  </div>
  </div>
</template>

<script>
export default {
  name: 'Chartusage',
  props: {
    userSubmitsProp: {
      type: Array,
      required: true
    }
  },
  data () {
    return {
      submits: this.userSubmitsProp,
      // chart data
      labels: [],
      dataset: [],
      // hover point
      mywidth: 3,
      mypointbordercolor: '#1976D2',
      hoverwidth: 3,
      hoverbackgroundcolor: '#636b6f',
      hoverbordercolor: '#ffd663'
    }
  },
  methods: {
    addChartLabels () {
      debugger
      for (let submit of Object.values(this.submits)) {
        this.labels.push(submit.timestamp)
      }
    },
    addChartdataset () {
      for (let submit of Object.values(this.usersubmits)) {
        this.dataset.push(submit.usage)
      }
    }
  },
  created () {
    this.addChartLabels()
    this.addChartdataset()
  }
}
</script>

<style>
.check-usage {
  margin: 20px 20px 30px 20px;
  box-shadow: 0 4px 70px -18px #707070;
  padding: 10px;
}

.chart {
  padding: 10px;
}
</style>

Upvotes: 4

Views: 12343

Answers (1)

Stephen Thomas
Stephen Thomas

Reputation: 14053

So previousSubmits in the Dashboard component is an empty array:

export default {
  name: 'Dashboard',
  data () {
    return {
      currentUserData: {},
      previousSubmits: []
    }
  },

And that's what's getting passed to the chartusage component as userSubmitsProp:

    <chartusage :userSubmitsProp="previousSubmits" />

Which is also referenced as submits in that child component's data:

  data () {
    return {
      submits: this.userSubmitsProp,

And then your code tries to call Object.values on an empty array:

Object.values(this.submits)

BTW, the idiomatic way to provide properties to a component is to use dashes rather than camelCase:

    <chartusage :user-submits-prop="previousSubmits" />

Upvotes: 3

Related Questions