Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
835 views
in Technique[技术] by (71.8m points)

nuxt.js - Nuxt JS Apollo data only available after page refresh

I am fetching some data using Apollo inside of Nuxt. Somehow, when navigating to that page I get an error of

Cannot read property 'image' of undefined

When I refresh the page, everything works as expected.

I have a found a few threads of people having similar issues but no solution seems to work for me :/

This is my template file right now:

/products/_slug.vue

<template>
  <section class="container">
    <div class="top">
      <img :src="product.image.url"/>
      <h1>{{ product.name }}</h1>
    </div>
  </section>
</template>

<script>
import gql from 'graphql-tag'

export default {
  apollo: {
    product: {
      query: gql`
        query Product($slug: String!) {
          product(filter: { slug: { eq: $slug } }) {
            slug
            name
            image {
              url
            }
          }
        }
      `,
      prefetch({ route }) {
        return {
          slug: route.params.slug
        }
      },
      variables() {
        return {
          slug: this.$route.params.slug
        }
      }
    }
  }
}
</script>

Basically the $apolloData stays empty unless I refresh the page. Any ideas would be much appreciated

EDIT Got one step closer (I think). Before, everything (image.url and name) would be undefined when navigating to the page for the first time.

I added:

data() {
    return {
      product: []
    };
  }

at the top of my export and now at least the name is always defined so if I remove the image, everything works as expected. Just the image.url keeps being undefined.

One thing I noticed (not sure how relevant) is that this issue only occurs using the , if I use a normal a tag it works but of course takes away the vue magic.

EDIT-2 So somehow if I downgrade Nuxt to version 1.0.0 everything works fine

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I stumbled on this issue as well, and found it hidden in the Vue Apollo documents.

Although quite similar to the OP's reply, it appears the official way is to use the "$loadingKey" property.

It's quite confusing in the documents because there are so many things going on. https://vue-apollo.netlify.com/guide/apollo/queries.html#loading-state

<template>
  <main
    v-if="!loading"
    class="my-8 mb-4"
  >
    <div class="w-3/4 mx-auto mb-16">
      <h2 class="mx-auto text-4xl text-center heading-underline">
        {{ page.title }}
      </h2>
      <div
        class="content"
        v-html="page.content.html"
      ></div>
    </div>
  </main>
</template>
    
<script>
import { page } from "~/graphql/page";
    
export default {
  name: 'AboutPage',

  data: () => ({
    loading: 0
  }),
    
  apollo: {
    $loadingKey: 'loading',
    page: {
      query: page,
      variables: {
        slug: "about"
      }
    },
  }
}
</script>

If you need to use a reactive property within vue such as a slug, you can do so with the following.

<template>
  <main
    v-if="!loading"
    class="my-8 mb-4"
  >
    <div class="w-3/4 mx-auto mb-16">
      <h2 class="mx-auto text-4xl text-center heading-underline">
        {{ page.title }}
      </h2>
      <div
        class="content"
        v-html="page.content.html"
      ></div>
    </div>
  </main>
</template>
    
<script>
import { page } from "~/graphql/page";
    
export default {
  name: 'AboutPage',
    
  data: () => ({
    loading: 0
  }),
    
  apollo: {
    $loadingKey: 'loading',
    page: {
      query: page,
      variables() {
        return {
          slug: this.$route.params.slug
        }
      }
    },
  }
}
</script>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...