'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>
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 |