0

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>
4
  • You can use useAsyncData instead of useFetch Commented Feb 12 at 11:20
  • Well I did that in the first place but I do get this error then: [nuxt] [useAsyncData] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching and for useFetch its the same: [nuxt] [useFetch] Component is already mounted, please use $fetch instead. See https://nuxt.com/docs/getting-started/data-fetching Commented Feb 12 at 12:32
  • Please include your attempt in the question, we can't magically guess what you did. Commented Feb 12 at 12:40
  • I did, didn't I? You can see the code up there. And regarding my last comment: just exchange useFetch with useAsyncData. They both work, but I do get the above mentioned error... I can add the working code though which gives me that warning. I will add it... Commented Feb 12 at 12:52

1 Answer 1

1

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]
  }
);
Sign up to request clarification or add additional context in comments.

2 Comments

Hm this almost works, but I get an error that I have an Invalid watch source. I tried to use toRef(props, 'contentId') to then watch that reactive prop. Still same error. I did manage to get it to work with using a normal watcher, watching contentId and then using the refresh() of useAsyncData: like const { data, refresh } = useAsyncData(.... How could I make this work with the standard watcher? Thanks a lot for the example how to use the fetching together with that unique key and the queryCollection funciton. 🙏
And if I watch the prop directly I get something like this: [Vue warn] Set operation on key "contentId" failed: target is readonly.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.