Home > other >  The data fetched from an API doesn't populate the table in NextJS
The data fetched from an API doesn't populate the table in NextJS

Time:05-13

I try to populate a table with an API call in NextJS. I use getStaticProps function to get the data and pass them to the component. I tried map() function to access each data in the object but it doesn't work and doesn't populate the required data. when I run the app the console outputs the below error.

Warning: data for page "/" is 150 kB, this amount of data can reduce performance.

When I checked the page source it has the full API object and I don't understand why it does that. Below I have put the code of index.js and CountriesTable.js

index.js

import Head from "next/head";
import CountriesTable from "../components/CountriesTable/CountriesTable";
import Layout from "../components/Layouts/layout";
import SearchInput from "../components/SearchInput/SearchInput";
import styles from "../styles/Home.module.css";

export default function HomePage({ countries }) {
    return (
        <Layout>
            <div className={styles.counts}>found {countries.length} countries</div>

            <SearchInput placeholder="Search for country" />

            <CountriesTable countries={countries} />
        </Layout>
    );
}

export const getStaticProps = async () => {
    const res = await fetch("https://restcountries.com/v3.1/region/asia");
    const countries = await res.json();

    return {
        props: {
            countries,
        },
    };
};

CountriesTable.js

import styles from './CountriesTable.module.css';

export default function CountriesTable({countries}) {
    return (
        <div>
        <div className={styles.heading}>
            <button className={styles.heading_name}>
                <div>Name</div>
            </button>

            <button className={styles.heading_population}>
                <div>Population</div>
            </button>
        </div>

        {countries.map((country) => { 
            <div className={styles.row}>
            <div className={styles.name}>{country.name}</div>
            <div className={styles.population}>{country.population}</div>
        </div>
        })}
        </div>
    );
};

How can I resolve the error in the console and populate the table with data? TIA!

CodePudding user response:

NextJS is a server rendered platform. Any props you pass to pages/components will be serialized in the source itself. Therefore, it is very important to trim data to fields which are necessary. Otherwise you will see entire json in the HTML source. (Working codesandbox)

Reduce the amount of data returned from getStaticProps, getServerSideProps, or getInitialProps to only the essential data to render the page.

As only name & population are required we can create a new dataset with these two properties only. This should get rid of the warning as well.

export const getStaticProps = async () => {
  const res = await fetch("https://restcountries.com/v3.1/region/asia");
  const countries = await res.json();
  const countriesWithNamePopulation = countries.map((country) => ({
    name: country.name.common,
    population: country.population
  }));
  return {
    props: {
      countries: countriesWithNamePopulation
    }
  };
};

countries.map needs a return statement

{countries.map((country) => {
        return (
          <div>
            <div>{country.name}</div>
            <div>{country.population}</div>
          </div>
        );
      })}

CodePudding user response:

I cannot reproduce your console warning but you are missing the return statement inside your map function.

This works for me:

            {countries.map((country, index) => {
                return(
                    <div key={index}>
                        <div>{country.name.common}</div>
                        <div>{country.population}</div>
                    </div>
                    )
                })}

Furthermore you need cannot display country.name as it is an object. I used country.name.common which is valid as it is a string. Additionally you need to add a key property to your div inside the map function.

  • Related