Reactivity lost when variable is used in function

44 Views Asked by At

I have a simple Vue 3 app with Vite that calls a Google sheets for data. I am missing something about reactivity in Vue 3. The following works fine

<template>
  <div v-if="ssData">{{ ssData.values[0][2] }}</div>
</template>

<script setup>
// Fetch the SS data
  const { data: ssData } = useFetch(ssURL);
</script>

The template updates with the data once fetch completes. But I want the user to retrieve data on button click:

<template>
  <h1>Senior Options</h1>

  <button @click="getSSValues">Get Data</button>

  <div v-if="ssData">{{ ssData.values[0][2] }}</div>
</template>

<script setup>
let ssData = ref(null);

 const getSSValues = () => {
    // eslint-disable-next-line no-unused-vars
    const { data } = useFetch(ssURL);
    ssData.value = data;

  };
</script>

This does not update the template when data is retrieved. I looked in Vue Devtools and I see the ssData object has data in it, so I am assuming I must be doing something wrong in terms of my understanding of reactivity.

How does one use a reactive variable from within a function so reactivity is maintained and template gets updated?

1

There are 1 best solutions below

3
quippe On

Try to move useFetch to the script tag and then run execute in getSSValues function.

<template>
  <h1>Senior Options</h1>
  <button @click="getSSValues">Get Data</button>
  <div v-if="ssData">{{ ssData.values[0][2] }}</div>
</template>

<script setup>
 const { data: ssData, execute } = useFetch(ssURL, { immediate: false });

 const getSSValues = () => {
    execute()
  };
</script>

To debug it further you can also try to display ssData.values in pre tag without array notation in template tag.

<template>
  <h1>Senior Options</h1>
  <button @click="getSSValues">Get Data</button>
  <pre v-if="ssData">
    {{ ssData.values }}
   </pre>
</template>