Home > database >  Problem getting API images to display in NextJS App
Problem getting API images to display in NextJS App

Time:11-21

This is my first time using NextJS and I'm trying to load 3 random dog breed images onto the app's webpage using the Dog.ceo API. I am able to see the three random dogs in the console from the console.log(data) line, but the images aren't being displayed. In this API there are only two properties - message (containing the image URL) and status (displaying 'success'). Any help in how to get these images to display? Also to note, I'm not using Typescript for this.

const defaultEndpoint = "https://dog.ceo/api/breeds/image/random/3";

export async function getServerSideProps() {
  const res = await fetch(defaultEndpoint);
  const data = await res.json();

  return {
    props: { data },
  };
}

export default function Home({ data }) {
  console.log("data", data);
  const { results = [] } = data;
  return (
    <div className={styles.container}>
      <Head>
        <title>Dog Breed App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <div className="grid">
          {results.map((result) => {
            const { message } = result;

            return (
              <div key={message}>
                <img src={message} alt=""></img>
              </div>
            );
          })}
        </div>
      </main>
    </div>
  );
}

I tried using "message" from the "data" variable to get the url for the image. But that isn't working.

CodePudding user response:

It's just a destructuring error. You have const { results = [] } = data;.

That line says: Find the property in my data object called results and if it doesn't exist, set it to an empty array. Your data object doesn't have a property called results. It has a property called message.

You could change this line to const { message = [] } = data and then just loop over the message array or you could just store the message array in the props.data property like this:

export async function getServerSideProps() {
  const res = await fetch('https://dog.ceo/api/breeds/image/random/3');

  // Destructure the response object here and 
  // rename the 'message' property as 'data'
  const { message: data } = await res.json();

  return {
    props: { data },
  };
}

// Destructure the props object to have access to the 
// property named data:
export default function Home({ data }) {
  return (
    <main>
      <div className="grid">
        {data.map((img) => (
          <div key={img}>
            <img src={img} alt="dog"></img>
          </div>
        ))}
      </div>
    </main>
  );
}

CodePudding user response:

you can use useEffect hook to load data and update to a state dogs. This will update render once on component creation.

const defaultEndpoint = "https://dog.ceo/api/breeds/image/random/3";
import React, { useState, useEffect } from 'react'


export default function Home({ data }) {
  const [dogs, setDogs] = useState([]);

  export async function getServerSideProps() {
    const res = await fetch(defaultEndpoint);
    const data = await res.json();
  
    console.log("data", data);
    setDogs(data)
  }
  useEffect(() => {
    getServerSideProps()
  }, [])
  
  return (
    <div className={styles.container}>
      <Head>
        <title>Dog Breed App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main>
        <div className="grid">
          {dogs.map((result) => {
            const { message } = result;

            return (
              <div key={message}>
                <img src={message} alt=""></img>
              </div>
            );
          })}
        </div>
      </main>
    </div>
  );
}

I'll suggest using [dependencies] in useEffect to control when it re-renders it like below

useEffect(() => {
      //
    
      return () => {
        // 
      }
    }, [dependencies])

  • Related