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