Home > Net >  Vue JS Composition API, call composable async function both in setup and in an event function
Vue JS Composition API, call composable async function both in setup and in an event function

Time:07-13

as "disclaimer" so to speak, kindly note that I'm relatively new to Vue and I am currently developing a data visualisation project, as a means to get acquainted with the concepts.

So, to retrieve the data from an API, I use the following function as a composable.

import {ref} from 'vue'
const getData = (endpoint) => {
    const data = ref([])
    const error = ref(null)
    const load = async() => {
      try{
        let response = await fetch("BASE_URL" endpoint)
        if (!response.ok){
          throw Error('Error when trying to fetch data')
        }
        data.value = await response.json()
      }
      catch (err){
        error.value = err.message
      }
    }
    return{data, error, load}
}
export default getData

Now, I retrieve the data from inside the setup function and display them on the template. What I need help with is making another API call after an @click event for example, and updating the data on the page.

My code looks like this below, in which the handleclick function doesn't work as intended. The desired result would be for the template to show data from endpoint2 after clicking the button. I may have a fundamental misunderstanding of some of the concepts, but that's why I ask the community for some help. Any help is greatly appreciated.

<template>
    <div>
      <button @click="handleClick">click me</button>
    </div>
    <div>{{data}}</div>
</template>

<script>
import {ref} from 'vue'
import getData from '../composables/getData'

export default {
  name: 'HomeView',
  setup(){
    const {data, error, load} = getData('endpoint1')
    load()

    const handleClick = () => {
            console.log('clicked')
            const {data, error, load} = getData('endpoint2')
            load()
        }
    return {data, handleClick}
  },
}
</script>

CodePudding user response:

The issue is here.

const {data, error, load} = getData('endpoint2')

This doesn't update the data returned by setup function at all, here you just assign variables called ( data, error, load ) and you don't use it.

I think you need to turn your composable function to async one instead of using load function.

And then set a ref with the initial value with the getData function.

And in the handle click function reset the ref

CodePudding user response:

getData is efficiently a composition function (they are conventionally called like useData to designate their purpose) but it's used incorrectly.

Composition functions are called directly in setup function/block. Any other usage depends on the implementation and needs to be additionally confirmed. That the function returns refs suggests that refs are supposed to be created once and then ref values are accessed.

It's not a good practice to put asynchronous side effects like load to setup. They are usually done on component mount, also lifecycle hooks and event listeners handle errors from promises, while a rejection from load() would remain unhandled (probably not the case here because of fail-safe code with catch).

Should be:

const {data, error, load} = useData('endpoint1')

onMounted(() => {
  return load()
})

const handleClick = () => {
  return load()
}

return {data, handleClick}
  • Related