Home > Mobile >  Mapping over an array in React typescript
Mapping over an array in React typescript

Time:10-03

I have a static data structure that I'm serving from my Next project's API route which is an array of objects with the following interface:

export interface Case {
  id: string;
  title: string;
  beteiligte: string[];
  gerichtstermin?: string;
  tasks?: [];
}

I'm using React Query to pull in the data in a component:

const Cases:React.FC = () => {
  const { data, status } = useQuery("cases", fetchCases);

  async function fetchCases() {
    const res = await fetch("/api/dummy-data");
    return res.json();
  }

  return (
    <DefaultLayout>
      <Loading loading={status === "loading"} />
      {data.cases.map((case)=><p>{case.name}</p>)}
    </DefaultLayout>
  );
}

export default Cases;

But when trying to map over the data I keep getting these squiggly lines and an incredibly ambiguous error:

enter image description here

enter image description here

I've tried absolutely everything I can think of and have searched far and wide through React Query documentation, typescript guides and of course many, many stackoverflow posts. Please help! (typescript newbie)

UPDATE:

When I type {data.cases.map(()=>console.log("hello")} there is no error at all. But as soon as I add a parameter to the anonymous function, the errors pop up: {data.cases.map((case)=>console.log("hello"))}

CodePudding user response:

  • In the case interface, you do not have "name" property.

  • you should be mapping only if success is true. you have to guard your code. see what you get console.log(data). also, use key prop when mapping

    {status === "success" && (
        // case is reserved word. use a different name
        {data.cases.map((caseItem) => (
          <p key={caseItem.id}>{caseItem.name}</p>
        ))}
    )}
    
  • case is a reserved word. If you use any other word it works

CodePudding user response:

I tried to reproduce your issue in sandbox and I managed to make it "transpile"

Sandbox link

  1. You have to add prop name of type string to the Case interface in order to use it
export interface Case {
  name: string;
  id: string;
  title: string;
  beteiligte: string[];
  gerichtstermin?: string;
  tasks?: [];
}

// in my example interface is named CaseResonse 
  1. I assume your API response looks like this
{ "data": { "cases": [] } }
  1. You have to define the API response to be usable:
interface GetCaseResponseWrapper {
  cases: Array<Case>;
}

// in my example it is array of CaseResponse
interface GetCaseResponseWrapper {
  cases: Array<CaseResponse>;
}

  1. You need to decorate your fetchCases to return GetCaseResponseWrapper
async function fetchCases() {
  const res = await fetch("/api/dummy-data");
  const jsonResult = await res.json();
  return jsonResult.data as GetCaseResponseWrapper;
}

  1. the data from the useQuery may be undefined, so you should use ?.
      {data?.cases.map((c) => (
        <p>{c.name}</p>
      ))}

Sandbox link

  • Related