I’m working with Vue 3.
If I write this:
<p v-for="(prs, index) in settings.pressure">{{settings.pressure[0].value}}</p>
I see the value correctly, while if I use this (the one I need):
<p>{{settings.pressure[0].value}}</p>
it throws an error:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading ‘0’)
How could it be defined in the first version and undefined in the second?
2
Answers
It seems that settings.pressure is undefined when the template is loaded.
You are able to
for in loop
an undefined element without throwing an error. Since it does not loop over anything,<p>{{settings.pressure?.[0].value}}</p>
will not be evaluated. As such it gives time for your settings.pressure state to be loaded which will render the element as expected.The code below will print "No error thrown"
Your second answer however, immediately access’s the first element of the array which is undefined. This will throw the error you have.
You may want to try using an optional so that an error is not thrown until the state is loaded.
<p>{{settings.pressure?.[0].value}}</p>
Brief explanation:
settings.pressure
is empty when component is mounted and gets populated shortly after. Therefore, when running the code outside ofv-for
it errors becausesettings.pressure
isundefined
. (It would fail similarly ifsettings.pressure[0]
wasundefined
). But whensettings.pressure
gets populated, thev-for
is run and at that time the code no longer errors, becausesettings.pressure[0]
is no longerundefined
. It’s the first element insettings.pressure
.The template code of the
v-for
directive (no matter what that code does), gets executed once for each item in the collection 1 being iterated.So when
settings.pressure
is empty or falsey ([]
,{}
,new Set()
,new Map()
,null
,undefined
,0
,NaN
,false
), it runs the template code once for each item in the collection: 0 times!When you run
settings.pressure[0].value
outside ofv-for
, ifsettings.pressure
isnull
orundefined
, JS will complain it can’t find property0
ofnull
orundefined
. If you initially used an empty array/object/map/set, the code would try to find the first item insettings.pressure
(which would beundefined
). And then it would error when attempting to accessvalue
ofundefined
.Whenever you try to access any property of
null
orundefined
, JavaScript will throw an error telling you they don’t have any properties (because they can’t have properties, by design) and therefore they can’t be queried for properties.Important side-note: if
settings.pressure[0]
, when populated, is a ref(), you don’t need.value
in<template />
. All refs are unwrapped by Vue automatically in template (which means you don’t.value
, like inside<script />
).1 – typically we use arrays with
v-for
, but it can also iterate over an object’s properties, over JavaScriptMap
s andSet
s and you can also pass a plain number to it (n
) and it will run the template code n times.