-2

I have a nuxt.js project: https://github.com/AzizxonZufarov/newsnuxt2 I need to update posts from API every minute without loading the page: https://github.com/AzizxonZufarov/newsnuxt2/blob/main/pages/index.vue

How can I do that?

Please help to end the code, I have already written some code for this functionality. Also I have this button for Force updating. It doesn't work too. It adds posts to previous posts. It is not what I want I need to force update posts when I click it.

This is what I have so far

<template>
  <div>
    <button class="btn" @click="refresh">Force update</button>
    <div class="grid grid-cols-4 gap-5">
      <div v-for="s in stories" :key="s">
        <StoryCard :story="s" />
      </div>
    </div>
  </div>
</template>

<script>
definePageMeta({
  layout: 'stories',
})
export default {
  data() {
    return {
      err: '',
      stories: [],
    }
  },
  mounted() {
    this.reNew()
  },
  created() {
    /* setInterval(() => {
              alert()
        stories = []
        this.reNew()
        }, 60000) */
  },
  methods: {
    refresh() {
      stories = []
      this.reNew()
    },
    async reNew() {
      await $fetch(
        'https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'
      ).then((response) => {
        const results = response.slice(0, 10)
        results.forEach((id) => {
          $fetch(
            'https://hacker-news.firebaseio.com/v0/item/' +
              id +
              '.json?print=pretty'
          )
            .then((response) => {
              this.stories.push(response)
            })
            .catch((err) => {
              this.err = err
            })
        })
      })
    },
  },
}
</script>

<style scoped>
.router-link-exact-active {
  color: #12b488;
}
</style>
kissu
  • 40,416
  • 14
  • 65
  • 133
Azizxon Zufarov
  • 107
  • 1
  • 3
  • 8
  • What do you want here? SPA-only, SSR, or SSG? Not all of them are compatible with what you want. Also, defined "update posts", do you want the user to manually refresh the page (F5) or it to be fetched? Is SEO important here? – kissu Dec 05 '22 at 16:25
  • @kissu SPA-only. no ssr or ssg. I want this: every minute posts must to be fetched without refreshing page itself programaticaly using setInterval. SEO is not important. – Azizxon Zufarov Dec 05 '22 at 16:29
  • @kissu Also I have a button with class btn. I need to fetch posts manually by clikcking it. – Azizxon Zufarov Dec 05 '22 at 16:31
  • @kissu It means I will have 2 functionalities: every mnute posts fetch again and again itself; second when user clicks button posts manually will be fetched. – Azizxon Zufarov Dec 05 '22 at 16:33
  • If SPA, then it's pretty doable for sure. `this.mounted` is not a thing in Nuxt. I recommend that you use [`refresh()`](https://nuxtjs.org/docs/internals-glossary/$nuxt#refreshing-page-data). Also, please use the `fetch()` lifecycle hook rather than `mounted` since you're using Nuxt. You can call the `refresh()` method upon a button click or as you tried, with a `setInterval`. Please share some code here as far as your progress and debugging process. Asking people to just fix your GitHub repo is not how this platform works. I'll gladly help you if you do your part. – kissu Dec 05 '22 at 16:37
  • @kissu I do not understand lifecycle hooks well. Can You suggest some resources which explains lifecycle hooks comparing with vanilla js? – Azizxon Zufarov Dec 05 '22 at 16:46
  • Start with Vue: https://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram Then you can read the one for Nuxt: https://nuxtjs.org/docs/concepts/nuxt-lifecycle#nuxt-lifecycle Most, you can focus on using `fetch()` as explained here: https://nuxtjs.org/docs/features/data-fetching#fetching-data – kissu Dec 05 '22 at 16:49
  • @kissu I am using : refresh() { this.$nuxt.refresh() } but I dont notice any changes on screem. Is it right? How can I know that my refresh method working? – Azizxon Zufarov Dec 06 '22 at 03:18
  • Please share an update snippet of code of what you tried. Also please check your network tab to find out any XHR requests – kissu Dec 06 '22 at 03:21
  • @kissu here is my code: https://github.com/AzizxonZufarov/newsnuxt2/blob/main/pages/index.vue. Sorry, You said that giving repo link is bad, but i do not how to show You, thats why I am showing my repo – Azizxon Zufarov Dec 06 '22 at 04:06
  • I've posted an answer [to both](https://stackoverflow.com/a/74696683/8816585) of your questions. – kissu Dec 06 '22 at 05:41

1 Answers1

0

This is how you efficiently use Nuxt3 with the useLazyAsyncData hook and a setInterval of 60s to fetch the data periodically. On top of using async/await rather than .then.
The refreshData function is also a manual refresh of the data if you need to fetch it again.

We're using useIntervalFn, so please do not forget to install @vueuse/core.

<template>
  <div>
    <button class="btn" @click="refreshData">Fetch the data manually</button>

    <p v-if="error">An error happened: {{ error }}</p>
    <div v-else-if="stories" class="grid grid-cols-4 gap-5">
      <div v-for="s in stories" :key="s.id">
        <p>{{ s.id }}: {{ s.title }}</p>
      </div>
    </div>
  </div>
</template>

<script setup>
import { useIntervalFn } from '@vueuse/core' // VueUse helper, install it

const stories = ref(null)

const { pending, data: fetchedStories, error, refresh } = useLazyAsyncData('topstories', () => $fetch('https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty'))

useIntervalFn(() => {
  console.log('refreshing the data again')
  refresh() // will call the 'topstories' endpoint, just above
}, 60000) // every 60 000 milliseconds

const responseSubset = computed(() => {
  return fetchedStories.value?.slice(0, 10) // optional chaining important here
})

watch(responseSubset, async (newV) => {
  if (newV.length) { // not mandatory but in case responseSubset goes null again
    stories.value = await Promise.all(responseSubset.value.map(async (id) => await $fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json?print=pretty`)))
  }
})

function refreshData() { refreshNuxtData('topstories') }
</script>
kissu
  • 40,416
  • 14
  • 65
  • 133