1

I am working on a personal project with Next.js and Typescript. I have an API call on the hello.ts that comes by default with the app. I added a JSON file on there. Currently, I am having issues mapping that JSON and rendering the content of it. At the moment, the JSON is inside the useState, but when I try to do something with it the browser and the console give me errors.

This is the hello.ts with a msaller JSON located here /pages/api/hello:

// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
import type { NextApiRequest, NextApiResponse } from 'next'

type Data = {
  clientName: string
  campaignName: string
  userName: string
  frames: {
    id: string
    asset: string
    subheading: string
    description: string
    link: string
  }[]
}

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>
) {
  res.status(200).json({
  userName: "username",
  frames: [
      {
          id: "1",
          asset: "",
          subheading: "Instagram",
          description: "",
          link: "someurl.com"
      },
      {
          id: "3",
          asset: "",
          subheading: "Facebook",
          description: "username Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean sollicitudin metus vitae",
          link: "someurl.com"
      }
  ] })
}

This is where I am calling the api located components/container:

import { useEffect, useState } from "react";

import { FrameContainerProps } from "../../types";

const FrameContainer: React.FC<FrameContainerProps> = () => {
    const  [apiDetails, setapiDetails] = useState<any>();

    useEffect(() => {
        fetch('http://localhost:3000/api/hello')
          .then((res) => {
            return res.json();
          })
          .then(
            (data) => {
                setapiDetails(data);
            },
            (err) => {
                return console.error(err);
            }
          );
    }, []);

    return (
        <>
            {Object.entries(apiDetails).map(detail => (
                <h3>{detail.frames[i].description ? detail.frames[i].description : ''}</h3>
            ))}
        </>
    )
}

export default FrameContainer;

Also, how can I render the data only if it has values inside?

1 Answer 1

1

Set the apiDetails default value to null and add a check to see if the data has been loaded.
Also, you should map on apiDetails.frames:

import { useEffect, useState } from 'react';

import { FrameContainerProps } from '../../types';

const FrameContainer: React.FC<FrameContainerProps> = () => {
  const [apiDetails, setapiDetails] = useState<any>(null);

  useEffect(() => {
    fetch('http://localhost:3000/api/hello')
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        setapiDetails(data);
      })
      .catch((err) => {
        return console.error(err);
      });
  }, []);

  if (!apiDetails) return <>Loading data...</>;

  return (
    <>
      {apiDetails.frames && apiDetails.frames.map((frame) => (
        <h3>
          {frame.description || ''}
        </h3>
      ))}
    </>
  );
};

export default FrameContainer;
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.