'Vuejs Cannot read properties of undefined? But properties are defined

So i have been working on a project of mine and ive come along something really strange which i cant seem to solve.

the issue: The code beneath with the v-for loop works IF i dont reload the website and just do ctrl + S to save the file (hotloading).

How ever if i do save and reload the page the following error appears: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'edges'). I would like to get the values stored in every node. How is this possible the value is there. Is there anyway to solve this?

How is it possible that in a hot update/load it works and in a normal reload it doesnt?

Could this be because the API gets requested after VueJs searches for the property? If anyone knows a solution to this please let me know. All the help is greatly appreciated.

my data:

{"data":
  {"customers":
    {"edges":[
      {"node": 
        {"id":"gid:\/\/shopify\/Customer\/543xxxx429","email":"xxxxxx@me.com",
         "phone":null}},
      {"node": 
        {"id":"gid:\/\/shopify\/Customer\/5653xxxx37","email":"xxxxxxx@live.nl",
         "phone":null}}
      {"node": 
        {"id":"gid:\/\/shopify\/Customer\/57xxxxx8117",
      "email":"xxxxxxxx@outlook.com",
        "phone":null}}

My code:

                <tr v-for="customer in customers.customers.edges" :key="customer">
                  <td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900">
                    {{ customer.node.id }}
                  </td>
                  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                    <!-- {{ test }} -->
                  </td>
                  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                    {{ customer.node.email }}
                  </td>
                  <td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
                    {{  customer.node.phone }}
                  </td>
                  <td class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
                    <a href="#" class="text-indigo-600 hover:text-indigo-900">Edit</a>
                  </td>
                </tr>
<script setup>
import PageComponent from "/src/components/PageComponent.vue";
import store from "../../store";
import { computed} from "vue";
store.dispatch('getCustomers');

const customers = computed(() => store.state.customers.data);
console.log(customers);

//const customers = computed(() => store.state.customers.data);
</script>

console.log(customers) Result console.log(customers)

My network tab from chrome: Network Tab



Solution 1:[1]

When you refresh the page, store.state.customers.data is not yet populated, so the computed value of customers is the initial state (probably an empty object), and customers.customers would be undefined, leading to the error you observed.

One solution is to use optional chaining when referencing edges from customers.customers in the v-for:

                                         ?
<tr v-for="customer in customers.customers?.edges">

Another solution is to conditionally render the row when customer.customer.edges exists:

                                                   ?
<tr v-for="customer in customers.customers.edges" v-if="customer.customers?.edges">

Note: Only Vue 3 supports optional chaining in the template. In Vue 2, you can replace it with an additional truthy check, as seen in this equivalent markup to the above:

<tr v-for="customer in customers.customers.edges" v-if="customers.customers">
<tr v-for="customer in customers.customers.edges" v-if="customers.customers && customers.customers.edges">

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 tony19