Skip to content
Advertisement

How to fetch and render object of objects in next js?

I have following code and I am trying to display the data from the object of objects. The error that I receive is TypeError: Cannot read properties of undefined. I understand that the data isn’t in the format of ‘array of objects’, however I still don’t know how to properly map it. I would appreciate some help here…

import Layout, { siteTitle } from '../components/layout';
import { useState, useEffect } from 'react'

export default function Home({ allPosts }) {  
  return (
    <Layout home>
      <Head>
        <title>{siteTitle}</title>
      </Head>
      <section>
        {Object.values(allPosts.bpi).map(({ section, idx }) => (
          <li className={utilStyles.listItem} key={idx}>
           {section.description}
          <br />
          {section.code}
          <br />
        </li>
        ))}
      </section>
    </Layout>
  );
}

export async function getStaticProps() {
  let data = [];
  let error = "";
  try {
    const res = await fetch(
      "https://api.coindesk.com/v1/bpi/currentprice.json",
    );
    data = await res.json();
  } catch (e) {
    error = e.toString();
  }

  return {
    props: {
      allPosts: data,
      error,
    },
  };
}

Logged data: enter image description here

Object looks like this

{
"chartName": "Bitcoin",
"bpi": {
      "USD": {
           "code": "USD",
           "symbol": "$",
           "rate": "20,220.5728",
           "description": "United States Dollar",
           "rate_float": 20220.5728
      },
     "GBP": {
           "code": "GBP",
           "symbol": "&pound;",
           "rate": "16,896.1488",
           "description": "British Pound Sterling",
           "rate_float": 16896.1488
      },
   }
}

Advertisement

Answer

You don’t access the USD and GBP objects. You are just getting their names. But you can access them by name like this:

<section>
    {Object.values(allPosts.bpi).map((section, idx) => (
        <li className={utilStyles.listItem} key={idx}>
           {allPosts.bpi[section].description}
            <br />
            {allPosts.bpi[section].code}
            <br />
        </li>
    ))}
</section>

EDIT

It should be section.description instead of allPosts.bpi[section].description. Same for the object code.

<section>
    {Object.values(allPosts.bpi).map((section, idx) => (
        <li className={utilStyles.listItem} key={idx}>
           {section.description}
            <br />
            {section.code}
            <br />
        </li>
    ))}
</section>
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement