Reputation: 2377
I am trying too loop through IndexCategories in a "standard" for loop. If I do so, and try to access url property, inside Image property, I get: url is undefined.
This is what I have tried:
<div v-for="(cat, index) in IndexCategories" :key="index">
{{cat.Title}} --> this does work fine.
{{cat.Image.url}} --> this does not work.
{{cat.Image}} --> this does print out all of the image object, unparsed.
</div>
This is giving me, url is undefined, even though it's there. The same is with id or name property. Everything is wrapped in a try catch, with await method, also I'm checking if the state is pending.
The api data looks like this:
"IndexCategories": [
{
"id": 1,
"Title": "Laptop",
"Image": {
"id": 10,
"name": "laptop.png",
"alternativeText": "",
"caption": "",
"width": 260,
"height": 163,
"formats": {
"thumbnail": {
"name": "thumbnail_laptop.png",
"hash": "thumbnail_laptop_debb5c2788",
"ext": ".png",
"mime": "image/png",
"width": 245,
"height": 154,
"size": 3.88,
"path": null,
"url": "/uploads/thumbnail_laptop_debb5c2788.png"
}
},
"hash": "laptop_debb5c2788",
"ext": ".png",
"mime": "image/png",
"size": 1.88,
"url": "/uploads/laptop_debb5c2788.png",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-04-06T17:59:16.000Z",
"updated_at": "2021-04-06T17:59:16.000Z"
}
},
{
"id": 2,
"Title": "Mac",
"Image": {
"id": 12,
"name": "mac.png",
"alternativeText": "",
"caption": "",
"width": 260,
"height": 163,
"formats": {
"thumbnail": {
"name": "thumbnail_mac.png",
"hash": "thumbnail_mac_5d35856985",
"ext": ".png",
"mime": "image/png",
"width": 245,
"height": 154,
"size": 2.7,
"path": null,
"url": "/uploads/thumbnail_mac_5d35856985.png"
}
},
"hash": "mac_5d35856985",
"ext": ".png",
"mime": "image/png",
"size": 1.37,
"url": "/uploads/mac_5d35856985.png",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"created_at": "2021-04-06T17:59:16.000Z",
"updated_at": "2021-04-06T17:59:16.000Z"
}
},
}
The complete code:
<template>
<p class="grid-small margin-center" v-if="$fetchState.pending">Wait for it</p>
<p class="grid-small margin-center" v-else-if="$fetchState.error">Could not fetch</p>
<div class="index" v-else>
<nuxt-link to="/" class="border p-4 text-center min-h-2" v-for="cat in indexData.IndexCategories">
<span>{{cat.Title}}</span>
{{cat.Image.url}}
</nuxt-link>
</div>
</template>
<script>
export default {
data() {
return {
indexData: [],
}
},
async fetch() {
try {
this.indexData = await fetch(
process.env.apiUrl + '/Index'
).then(res => res.json());
} catch (e) {
console.log(e)
}
}
}
</script>
Upvotes: 0
Views: 792
Reputation: 8329
This is not a Vue
or Nuxt
issue, but how fetch
works in JavaScript
: if you are using fetch
, you have to unwrap the json()
too:
const url = 'https://jsonplaceholder.typicode.com/todos/1';
// Function #1 - no result
(async function() {
const response = await fetch(url)
const json = response.json()
console.log('json1:', json) // expected: json1: {}
})();
// Function #2 - expected result
(async function() {
const response = await fetch(url)
const json = await response.json()
console.log('json2:', json) // expected: json2: {/* object */}
})();
Your code now is like Function #1
above. You should change to this:
async fetch() {
try {
const response = await fetch(process.env.apiUrl + '/Index')
const json = await response.json()
this.indexData = json
} catch (e) {
console.log(e)
}
}
With the .then()
you are not await
ing res => res.json()
.
Try not to mix await
& Promise
-.then()
. Although await
is just a "syntactic sugar" on Promise
, they provide different code(ing) possibilities, and it's easy to loose track of what you're doing exactly :)
Upvotes: 1