Home > Blockchain >  Use effect and show data in typescript
Use effect and show data in typescript

Time:06-21

I'm writing a code in type script that needs to hit an URL and show the data in my component. I started recently with TS, and it is quite confusing coming from JS :-(. Here is the code that I have

import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";

interface ParamTypes {
  id: string;
}

const SingleProductPage = () => {
  const { id } = useParams<ParamTypes>();
  const [data, setData] = useState();
  const [isLoading, setIsLoading] = useState(false);
  const fetchProduct = async () => {
    setIsLoading(true);
    const response = await fetch(
      "myAPIEndpoint"
    );
    const responseJson = await response.json();
    console.log(await responseJson.response);
    setIsLoading(false);
    setData(await responseJson.response);
  };

  useEffect(() => {
    fetchProduct();
  }, [id]);

  if (isLoading=) {
    return <h1>Loading</h1>;
  } else {
    console.log(JSON.stringify(data.landingPageUrl));

    return <h1>Loaded - {data.landingPageUrl}</h1>;
  }
}; 

export default SingleProductPage;

My API returns a response in the format.

{
  "response": {
    "landingPageUrl": "https://google.com",
    "name": "John",
    "Job": {
      "name": "google",
      "designation": "s/w engg"
    }
  }
}

From this, I want to show landingPageUrl on my page. And also, how can I destructure the object? In JS we use const { name, id } = data;

CodePudding user response:

You have to describe the type of your response in your async function. You didn't tell typescript what kind of object it returns

Define type of response:

type ApiResponse = {
  "response": {
    "landingPageUrl": string;
    "name": string;
    "Job": {
      "name": string;
      "designation": string;
    }
  }
}

Then tell typescript what you expect in reponseJson variable

 const fetchProduct = async () => {
    setIsLoading(true);
    const response = await fetch(
      "myAPIEndpoint"
    );
    const responseJson: ApiResponse = await response.json();
    console.log(await responseJson.response);
    setIsLoading(false);
    setData(await responseJson.response);
  };

Also, you should declare useState with data

const [data, setData] = useState<IApiResponse["response"] | null>(null);

Then you can use data in your render with the correct structure. But because initially, your data is null or undefined you cannot use destruction at once. You should check if data exists before

CodePudding user response:

First of all, you can add typing for the state (it's optional, but that way is more convenient)

interface jobObjType {
    name: string
    designation: string
}
interface dataType {
    landingPageUrl?: string
    name?: string
    Job?: jobObjType
}
const [data, setData] = useState<dataType>({});

then check how it is going:

console.log("data check", data)

and render some like this::

<h1>Loaded - {data.landingPageUrl||"---"}</h1>

By the way, in your code goes some mistakes:

if (isLoading=)

replace to:

if (isLoading)

And also, how can I destructure the object? In JS we use const { name, id } = data; Blockquote

In TS it works tottaly the same as in JS, but you also can add types:

const { name, id}: { name: string; id: string} = data
  • Related