redshift
redshift

Reputation: 5227

Nuxt3: How to refresh useFetch data on user interaction?

In my Nuxt3 app I have a comments component that renders and lists comments for a blog post. This works fine on SSR on initial page load, but when the user interacts with the page and selects a sort order via a drop down list, I am unsure how to re-fetch the data again in Nuxt3.

At this stage, do I use the mounted hook ?

Here's the menu they will select:

enter image description here

As stated, the page initially loads showing the "newest" comments. Here's the code:

Comments.vue:

<template>
  <section>
    <header>
      <CommentsSort @sort-comments-event="sortComments" />
    </header>
    <div>
      <aside>
        <CommentsAdd @refresh-comments-list-on-add="refreshCommentsList" />
      </aside>

      <div>
        <AppSpinner v-if="pending" />
        <CommentsList :comments="data" v-else />
      </div>
    </div>
  </section>
</template>

<script setup>

const route = useRoute()

const { pending, data, refresh } = await useFetch(
  `/api/comments/newest/${route.params.id}`
)

const refreshCommentsList = () => {
  refresh()
}

onMounted(() => {
  sortComments(e)
})

const sortComments = async (e) => {
  switch (e) {
    case 'oldest':
      const { data } = await useFetch(
  `/api/comments/oldest/${route.params.id}`
)
      break
    // case 'likes':
    //   // TO DO
    //   break
  }
}
</script>

And the comment sort component: CommentsSort.vue:

<template>
  <select
    v-model="selected"
    @change="sortCommentsEvent"
  >
    <option disabled value="">Sort by</option>
    <option value="newest">Newest</option>
    <option value="oldest">Oldest</option>
    <!-- <option value="likes">Likes</option> -->
  </select>
</template>

<script setup>
const emits = defineEmits(['sort-comments-event'])
const selected = ref('newest')

const sortCommentsEvent = () => {
  const sortBy = selected.value
  emits('sort-comments-event', sortBy)
}
</script>

When user selects the "oldest" drop down value item, how do I reload the data ? I confirm I am able to emit the event from CommentsSort to the parent Comments component, but not sure how to "swap" the initial page data with the "oldest" event data. How would I write the "sortComments" function in the Comments.vue component to handle the data update change?

Upvotes: 1

Views: 7837

Answers (1)

Alex Howez
Alex Howez

Reputation: 62

What refresh does is recall useFetch. Here instead of hard-coding "newest", use state to change it.

const { pending, data, refresh } = await useFetch(
  `/api/comments/newest/${route.params.id}`
)

For example you could have

const aroute = ref("newest");

const { data, pending, error, refresh } = await useFetch(`/api/comments/${aroute.value}/${route.params.id}`)

So onClick have a function that changes "aroute" state from newest to oldest and then call refresh().

Upvotes: 2

Related Questions