menu

Questions & Answers

Why can't I fetch and display data from this API in Nuxt 3?

I've followed many examples online on how to fetch a list of names from an API in Nuxt 3 such as the following and they always work as expected but have had no luck replicating the same results for a particular API that I need to use.

<template>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
</template>
<script setup>
  const { data : users } = await useFetch('https://jsonplaceholder.typicode.com/users')
</script>

Here is the API I've tried to use following the above example without success. It contains a list of stores listed here as shops here. https://mocki.io/v1/3fa1924f-6c6b-4d49-b9ec-d91f6da13c3c

As you see here on Stackblitz it works fine. https://stackblitz.com/edit/github-hk8kro?file=pages/index.vue

I assumed that the following code would work but I get an error saying 500 Cannot read properties of null (reading 'name') as you can see here as well in Stackblitz. https://stackblitz.com/github/mike-420/fetchingdata2?file=README.md

<template>
    <ul>
      <li v-for="shop in shops" :key="shop.id">
        {{ shop.name }}
      </li>
    </ul>
</template>
<script setup>
  const { data : shops } = await useFetch('https://mocki.io/v1/3fa1924f-6c6b-4d49-b9ec-d91f6da13c3c')
</script>

Any suggestions anyone please?

Answers(2) :

In script setup use:

const shops = ref()
const { data : shopsData } = await useFetch('https://mocki.io/v1/3fa1924f-6c6b-4d49-b9ec-d91f6da13c3c')
shops.value = shopsData.value.data.shops

500 is just a generic something went wrong on the server error, and because this HTML is being rendered on the server, it's producing that error code.

The issue is asynchronous JS. Before you've retrieved the stores data from the API, you are attempting to render data that has not made its way to your server yet. So according to your app, shop.name does not exist when it attempts to render.

There are many ways to deal with this issue.

For example you can either wrap that block of code in a v-if statement that checks if the stores object is empty.

Or you can implement optional chaining in your template to render some placeholder text.

Comments:
2023-01-19 23:10:05
Thank you, I appreciate the response. It has shown me that still have a lot to learn. I have no idea how to do what you are suggesting and am trying to review the fundamentals to hopefully understand it a little better.
2023-01-19 23:10:05
What part exactly? I can edit my answer to add sone clarity.
2023-01-19 23:10:05
I just finished going through more than half a dozen tutorials on this topic, thought I was making progress, but am still not getting it right.
2023-01-19 23:10:05
I just finished going through over more than half a dozen tutorials on the topic, thought I was making progress, but I still can't get it right. Why is it that the following example of one of the tutorials that I showed you on Stackblitz works fine the way it is but when I enter the other Mocki API I'm trying to use and change the rest of the code to match it it doesn't? stackblitz.com/edit/github-hk8kro?file=pages%2Findex.vue
2023-01-19 23:10:05
I got excited when I was able to see the name and address from one of the stores appear in the console log using the following code but was unable to get it to show on the screen when I tried the rest of what was performed in the tutorial. <template> <div> <h1>API test</h1> </div> </template> <script setup> const api_url = 'mocki.io/v1/3fa1924f-6c6b-4d49-b9ec-d91f6da13c3c'; async function getISS() { const response = await fetch(api_url); const data = await response.json(); console.log(data.data.name); console.log(data.data.address); } getISS(); </script>
2023-01-19 23:10:05
I've been working on this for weeks now and almost gave up but recently discovered that my API was returning the data in the wrong json format. According to the following video It seems as though I need to convert it to a string and then back to an json object as they did in the following video to be able to pull data from it but just need to figure out exactly how from a url now. youtube.com/watch?v=2NsfIgUBxDI