simon
simon

Reputation: 2377

Nuxt/Vue access object in object

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

Answers (1)

muka.gergely
muka.gergely

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:

Snippets with different results:

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

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 awaiting res => res.json().


SUGGESTION

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

Related Questions