0

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>
1
  • 2
    Your code seems to be right, can you share a fiddle to make it easier for debugging? Commented Apr 17, 2021 at 20:57

1 Answer 1

1

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 :)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.