Home > Enterprise >  Next.js Typescript handle of JSON Object
Next.js Typescript handle of JSON Object

Time:07-20

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?

CodePudding user response:

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;
  • Related