jonas
jonas

Reputation: 411

Error message when trying to pass data from component to page in Nuxt

I've created a component in Nuxt to get data from a Firestore database and would like to show that data in a page I created.

When I embed the component in a page I keep getting the error:

Property or method "provinces" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.

Now, when I copy the code from the component in the page it works just fine, so I assume the problem is with passing the data between the component and the page.

Full code of the component in components/index.vue :

  <template>
      <section class="container">
        <div class="index">
          <div v-for="province in provinces" :key="province.id">
        <div class="div_title">
          <h2>{{ province.name_nl }}</h2>
        </div>
           </div>
        </div>
      </section>
    </template>

<script>
// import { VueperSlides, VueperSlide } from 'vueperslides'
// import 'vueperslides/dist/vueperslides.css'
import firebase from 'firebase'
// import fireDb from '@/plugins/firebase.js'
export default {
  name: 'Index',
  components: {
    //  VueperSlides,
    //  VueperSlide
  },
  data: function() {
    return {}
  },

  async asyncData() {
    const moment = require('moment')
    const date = moment(new Date()).format('YYYY-MM-DD')
    const housesArray = []
    const provincesArray = []

    await firebase
      .firestore()
      .collection('provinces')
      .orderBy('name_nl')
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          provincesArray.push(doc.data())
        })
      })

    await firebase
      .firestore()
      .collection('houses')
      .where('valid_until', '>', date)
      .get()
      .then(querySnapshot => {
        querySnapshot.forEach(doc => {
          housesArray.push(doc.data())
        })
      })

    return {
      provinces: provincesArray,
      houses: housesArray
    }
  }
}
</script>

<style scoped>
div {
  text-align: center;
}

h2 {
  margin-top: 5vh;
  margin-left: auto;
  margin-right: auto;
  width: 95vh;
}
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
p {
  text-align: left;
}
li {
  min-width: 100% !important;
  margin-left: 0px;
  text-align: left;
}
</style>

Page where I insert the component in pages/index.vue:

<template>
  <v-layout column justify-center align-center>
    <v-flex xs12 sm8 md6>
      <div class="text-xs-center">
        <logo />
        <tabs />
        <index />
      </div>
    </v-flex>
  </v-layout>
</template>

<script>
import Logo from '~/components/Logo.vue'
import Tabs from '~/components/Tabs.vue'
import firebase from 'firebase'
import Index from '~/components/Index.vue'

export default {
  components: {
    Logo,
    Tabs,
    Index
  },
  data: function() {
    return {}
  }
}
    </script>

I would expect the page to display the data that I retrieved when I import the component into the page but I keep getting the same error.

Should I be using the Nuxt store to transfer data between a component and a page or am I doing something else wrong?

Upvotes: 0

Views: 928

Answers (1)

Dieterg
Dieterg

Reputation: 16368

The lifecycle hook asyncData is not know within Vue components. It's only known in Nuxt pages.

It's better to do the data request within your pages component and pass it as a property to your component:

pages/index.vue

<template>
   <index :houses="houses" />
</template>
<script>
const delay = time => new Promise(resolve => setTimeout(resolve, time)); 

export default {
   async asyncData() {
     // fake data
     await delay(500);

     return {
       houses: [...]
     }
   }
}
</script>

components/index.vue

<template>
  <pre>{{ houses }}</pre>
</template>
<script>
export default {
   props: {
      houses: {
        required: true,
        type: Array
      }
   }
}
</script>

Upvotes: 1

Related Questions