thebenCA
thebenCA

Reputation: 159

Nuxt @onloadstart not triggering function using beforeCreate

New to Nuxt and SSR. What I'm trying to do is straightforward: I'm trying to trigger a function before the page loads that will SSR my firestore data. If I add a button with @onclick, it works fine. But when I try to replace the Button/OnClick with @onloadstart or something similar, nothing happens.

What am I missing? I suspect I’m thinking about this through a client side lens. Not a SSR lens.

 <template @onloadstart="beforeCreate()">
  <section>
    <div>
      <div v-for="article in articles" id="articleCardList" :key="article">
        <v-card elevation="1" outlined>
          <div class="d-flex">
            <v-avatar class="ma-1" size="125" tile>
              <v-img :src="article.thumbnail"></v-img>
            </v-avatar>
            <div>
              <v-card-title
                class="text-h5 text-wrap d-flex justify-space-between text-caption"
                v-text="article.title"
              >
                {{ article.title }}
              </v-card-title>
            </div>
          </div>
        </v-card>
      </div>
    </div>
  </section>
</template>
<script>
import { fireDb } from '~/plugins/firebase.js'
export default {
  data() {
    return {
      articles: [],
    }
  },

  methods: {
    async asyncData() {
      this.articles = []

      await fireDb
        .collection('articles')
        .get()
        .then((querySnapShot) => {
          querySnapShot.forEach((doc) => {
            this.articles.push({
              id: doc.id,
              title: doc.data().title,
              description: doc.data().description,
              thumbnail: doc.data().thumbnail,
              date: doc.data().date,
              link: doc.data().link,
              source: doc.data().source,
            })
            console.log(this.articles)
          })
        })
    },
    beforeCreate() {
      window.addEventListener('beforeCreate', this.asyncData)
    },
  },
}
</script>

Upvotes: 2

Views: 372

Answers (1)

tony19
tony19

Reputation: 138216

You're close to a working solution in terms of having the component automatically fetch data before the page loads. Instead of beforeCreate, you'd use the asyncData hook (which seems to be your initial attempt).

The problem is you've declared asyncData as a component method, but it needs to be at the top level of the object definition for it to be used as a component hook.

export default {
  // ✅ declared as a hook
  asyncData() {...},

  methods: {
    // ❌ this should be at the top level
    asyncData() {...} 
  },
}

Be aware that asyncData can only be used in page or layout components. Otherwise, you need to switch to the fetch hook.

asyncData() has no access to this (as it's run before the page component), so those references should be removed. Instead, asyncData() should return an object of data similar to that returned from data() (i.e., { ​articles }):

export default {
  ​asyncData() {
    ​const articles = []

    ​await fireDb
      ​.collection('articles')
      ​.get()
      ​.then((querySnapShot) => {
        ​querySnapShot.forEach((doc) => {
          ​articles.push(/*...*/)
        ​})
      ​})

    console.log(articles)
    return { articles }
  }
}

Upvotes: 2

Related Questions