简体   繁体   中英

Nested useFetch in Nuxt 3

How do you accomplish nested fetching in Nuxt 3? I have two API's. The second API has to be triggered based on a value returned in the first API.

I tried the code snippet below, but it does not work, since page.Id is null at the time it is called. And I know that the first API return valid data. So I guess the second API is triggered before the result is back from the first API.

<script setup>
  const route = useRoute()
  const { data: page } = await useFetch(`/api/page/${route.params.slug}`)
  const { data: paragraphs } = await useFetch(`/api/page/${page.Id}/paragraphs`)
</script>

Obviously this is a simple attempt, since there is no check if the first API actually return any data. And it is not even waiting for a response.

In Nuxt2 I would have placed the second API call inside .then() but with this new Composition API setup i'm a bit clueless.

You could watch the page then run the API call when the page is available, you should paragraphs as a ref then assign the destructed data to it :

<script setup>
const paragraphs = ref()

const route = useRoute()

const { data: page } = await useFetch(`/api/page/${route.params.slug}`)


watch(page, (newPage)=>{
    if (newPage.Id) {

      useFetch(`/api/page/${newPage.Id}/paragraphs`).then((response)=>{
         paragraphs.value  = response.data

     })
        
    }
}, {
    deep: true,
    immediate:true
})
</script>

One solution is to avoid using await . Also, use references to hold the values. This will allow your UI and other logic to be reactive.

<script setup>
  const route = useRoute()
  const page = ref()
  const paragraphs = ref()
  useFetch(`/api/page/${route.params.slug}`).then(it=> {
     page.value = it
     useFetch(`/api/page/${page.value.Id}/paragraphs`).then(it2=> {
        paragraphs.value = it2
     }
  }
</script>

You can set your 2nd useFetch to not immediately execute until the first one has value:

<script setup>
  const route = useRoute()
  const { data: page } = await useFetch(`/api/page/${route.params.slug}`)
  const { data: paragraphs } = await useFetch(`/api/page/${page.value?.Id}/paragraphs`, {
    // prevent the request from firing immediately
    immediate: false,
    // watch reactive sources to auto-refresh
    watch: [page]
  })
</script>

You can also omit the watch option there and manually execute the 2nd useFetch . But for it to get the updates, pass a function that returns a url instead:

const { data: page } = await useFetch(`/api/page/${route.params.slug}`)
const { data: paragraphs, execute } = await useFetch(() => `/api/page/${page.value?.Id}/paragraphs`, {
  immediate: false,
})

watch(page, (val) => {
  if (val.Id === 69) {
    execute()
  }
})

You should never call composables inside hooks.

More useFetch options can be seen here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM