I am using the Vue framework , [Quasar].
This is the error it shows in the console:
[Vue warn]: Error in render: "TypeError: Cannot read property 'charAt' of undefined"
This is my code:
<template>
<q-page class="flex q-pa-md">
<q-list class="full-width" separator="">
<q-item
v-for="(user, key) in users"
:key="key"
to="/notes"
clickable
v-ripple
>
<q-item-section avatar>
<q-avatar color="teal" text-color="white">
{{ user.name.charAt(0) }}
</q-avatar>
</q-item-section>
</q-item>
</q-list>
</q-page>
</template>
<script>
import { mapGetters } from "vuex";
export default {
/* data() {
return {
users: [
{
id: 1,
name: "Robert",
online: true
},
{
id: 2,
name: "Sofia",
online: false
}
]
};
}, */
computed: {
...mapGetters("store", ["users"])
}
};
</script>
I have tried sending the values from a [data] object and it has worked correctly, however the value comes from a [store], in a [computed()] property, when I send it from there it is when the page goes blank and shows the initial error.
The problem is not really related to
Quasar
but toVue
or evenJavascript
, a common mistake is to write chartAt with "t" (which would mean chart ), instead ofcharAt
(which would be character ).The following example shows how it should normally work
You must evaluate the value that is coming to you and also how you are writing it.
Something that occurs to me is that the variable
user
is not available when the code starts executing, if possible put the variable inside the elementdata
or in the propertycomputed()
in case the value comes from astore
.As a last recommendation, validate that all the elements of your object exist and that there isn't a
undefined
.Depending on the content of the data and its origin, at certain points in the component's lifecycle you may operate on an undefined or invalid value.
In your specific case you try to get the initial of a user
Which presupposes that the variable user (in this case it is the item of an array, but this is anecdotal because an empty array does not enter the loop),
In your example with
data
How your component gets the data from the store
it would be necessary to see how it is initialized. For example:
It would explain that the array is not empty and yet contains an invalid user.
One option is to put an IF or several in the template:
Another option is to use a computed property to filter the data or marshall it to that structure.
But that's brittle, involves unnecessary coupling, and is confusing to maintain, if
user
it'snull
already passed the filter (JS mysteries) to begin with. Strictly speaking, the check should beuser.constructor === Object
but again, that object can come from having instantiated a classUser
.... if the component does not know or control the origin of it,users
it is looking for problems.I think it's more practical and easier to maintain an explicit coalescence in the template:
I mean
With that, the component only knows the minimum of the data, it doesn't matter where it comes from or other details of its structure.
The
string
one that you send to the view through VueJS is still an iterable element; then it should be enough to indicate the position to which you want to access in this way:From a structure like the following
Now if your data is inside an object inside the main it would be
data
like this:You can access it this way:
With which you will have the letter a when indicating that from the iterable object you obtain the element that is in position 0 as it is as if it were a vector