DEV Community

peacebind
peacebind

Posted on

React TS Interface and API Calls

Hi community,

I am pretty new to React with TS or web dev in general. I've been struggling on how to design a interface to match up with the data structure from an api call.

Here's the App.tsx file, and url of the fetch call "https://datausa.io/api/data?drilldowns=Nation&measures=Population"

import React from 'react';
import './App.css';

interface OuterModel {
  data: InnerModel[];
  source: object;
}

interface InnerModel {
  idNation: string;
  nation: string;
  idYear: number;
  year: string;
  population: number;
  slugNation: string;
}

function App() {
  const url = "https://datausa.io/api/data?drilldowns=Nation&measures=Population";
  const [data, setData] = React.useState<InnerModel[]>([]);

  function getData(): Promise<InnerModel[]> {
    return fetch(url).then(res => res.json()).then(result => (result as OuterModel).data as InnerModel[]);
  }

  React.useEffect(() => {
    getData().then(item => setData(item));
  }, [])

  return (
  <div>
    <h1>{data.length}</h1>
    <ul>
      {data?.map((item, idx) => <li key={idx}>{item.population}</li>)}
    </ul>
  </div>)
}

export default App;

Enter fullscreen mode Exit fullscreen mode

I suppose the fetch call was successful, as h1 showed the count of array. yet the unordered list is always blank. don't know what the problem is. The interface? The way I used hooks? these no errors in console, but it's just not right.

Image description

Also, I wonder if I'm doing this the right way. It seems I have to make a call first, say in browser console, to see the structure of returned json, then I can declare an interface for it. I find it a bit awkward. Are there better approaches?

Appreciate any help on this.

Discussion (1)

Collapse
peacebind profile image
peacebind Author

well, problem solved. The interface declaration should be like this:

interface InnerModel {
"ID Nation": string;
Nation: string;
"ID Year": number;
Year: string;
Population: number;
"Slug Nation": string;
}