Merc
Merc

Reputation: 4570

Refetching content with nuxt content using $fetch or useFetch with watch

I use nuxt with nuxt content (https://content.nuxt.com/). I have a component that needs to refetch some content while watching content ids.

I don't know how I can use $fetch or useFetch together with the watch option (https://nuxt.com/docs/getting-started/data-fetching#watch).

I am currently trying things like:


const props = defineProps({
  contentId: {
    type: String,
    required: true,
  },
})

const id = ref(null)

watch(
  () => props.contentId,
  (newId) => {
    console.log('newId: ', newId)
    id.value = newId
  },
)

const { refresh } = await useFetch(
  () =>
    queryCollection('popups')
      .where('stem', '=', `popups/en/${id.value}`)
      .first(),
  {
    watch: [id],
    onResponse({ response }) {
      console.log('response: ', response)
    },
  },
)

But useFetch seems to expect a url instead of this function returning the queryCollection-stuff.

Maybe it would be possible to directly watch the props, I just reassign it to the ref id, because I got an error that I had an unwatchable source when watching contentId directly.

====Edit:=====

And here is also my currently working solution that gives me that warning to use $fetch instead:

[nuxt] [useAsyncData] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching

<script setup>
const { locale } = useI18n()

const props = defineProps({
  contentId: {
    type: String,
    required: true,
  },
})


const popupContent = ref(null)

watch(
  () => props.contentId,
  (newId) => {
    fetchContent(newId)
  },
)

const fetchContent = async (id) => {
  if (!id) return

  console.log('id: ', id)

  const { data } = await useAsyncData(() =>
    queryCollection('popups')
      .where('stem', '=', `popups/${locale.value}/${id}`)
      .first(),
  )
  if (data?.value) {
    popupContent.value = data?.value
  } else {
    console.error('No popup content found for ID: ', id)
  }
}



onMounted(() => {
  fetchContent(props.contentId.value)
})
</script>

Upvotes: 0

Views: 50

Answers (1)

Reyno
Reyno

Reputation: 6525

There are a few misconceptions, useAsyncData isn't a drop in replacement for useFetch. There are a few key differences.

useFetch requires a url and some optional options.

useAsyncData requires a key, a function that returns data and some optional options.

const { locale } = useI18n()

const props = defineProps({
  contentId: {
    type: String,
    required: true,
  },
})

const { data, error, status } = useAsyncData(
  `popups/${locale.value}/${props.contentId}`, // unique key used for caching.
  () => {
    return queryCollection('popups')
      .where('stem', '=', `popups/${locale.value}/${id}`)
      .first();
  },
  {
    watch: [props.contentId]
  }
);

Upvotes: 1

Related Questions