Franco Alemandi
Franco Alemandi

Reputation: 345

Properly accesing to reactive array in Vue 3

I'm working on my Vue 3 app and I'm experiencing some troubles on making things work as expected.

What I need is to properly access a reactive array. Let me show you the code for clarifying purposes:

I have a global store store/questions/index.js with the following code:


const useQuestionsAndAnswers = () => {
    const data = reactive([])
    const getQuestionsAndAnswers = async () => {
      const response = await fetch('../../../db/questions.json')
      const fetchedData = await response.json();
      if(response.status === 200) {
        fetchedData.data.forEach(obj => data.push(obj))
        console.log(data[0]);  <--------- // This console.log works ok
      } else {
        console.log('Something went wrong')
      }
    };
      
    onMounted(() => {
        getQuestionsAndAnswers();
    });

    return { data }
}

export default useQuestionsAndAnswers;

If I run console.log(data[0]) I get the object I expect. So let's say it is working properly.

As you may realize, I want this data to be used on some Vue component. Well, the component is the next one:

components/calculator/Questions.vue:

<template>
  <div class="block max-w-4xl" v-if='data'>
    <h3 class='py-4'>Seleccioná la opción que mejor te describa</h3>
    {{ data[0] }} // Same as the console.log I showed you before.
  </div>
</template>

<script>
import useQuestionsAndAnswers from '../../store/questions/index.js'
export default {
  setup() {
    const  { data }  = useQuestionsAndAnswers();

    console.log(data)

    return {
      data,
    }
  }
}
</script>

And here is the part where things went weird. The binding data in DOM {{ data[0] }} works well and displays the entire object corresponding to that position, but if I try to access to question key as data[0].question it shows the data but if I refresh the page I got undefined. It seems like I'm missing reactivity.

The other problem is happening inside my setup() function. If I console.log(data) I get the expected Proxy with my array. But, if I try to access one object from the array mentioned console.log(data[0]) I got undefined once again.

For last, I'll show you an example of the json I'm receiving:

{
    "data": [
        {
            "question" : "Estás en medio de una pandemia mundial y estatizas una conocida empresa de alimentos (su nombre empieza con V de Vicentín) que no le paga a sus acreedores hace años. Qué harías ante el embate de Clarín?",
            "image": "@/assets/alberto.png",
            "id": 1,
            "answers": [
                {
                    "id": 1,
                    "answer": "Me haría el picante unos días y después me tiraría atrás.",
                    "points": 2,
                    "slug": "haria-el-picante"
                }
            ]
        }
    ]
}

So what I want is to properly access to the array and displays the data I want to.

Thanks in advance!

Upvotes: 2

Views: 4944

Answers (1)

Franco Alemandi
Franco Alemandi

Reputation: 345

In case that someone is going through the same I would tell you that the solution was so so simple:

With the v-if='data' I thought I was checking if the array actually exists but as you may know Vue 3 works with Proxy when dealing with objects so I was actually checking if that objects exists.

In that case the solution was simply add length to my sentence: v-if='data.length > 0'solved the whole problem. The same works inside my setup() function in case you need to work out with your array inside the <script>.

That's it.

Upvotes: 2

Related Questions