I am currently learning TypeScript in React so i was working on learning how to make API request with typescript I am fetching a single data by Id the result of the api request is displaying on my web page but i encountered an error the typescript compiler is saying Property does not exits here is my code
import { To, useParams } from "react-router-dom";
import axios from "axios";
import { useState, useEffect } from "react";
const SinglePOST = () => {
type Todo = {
title: string;
body: string;
userId: number;
id: number;
};
const { id } = useParams();
const [data, setData] = useState<Todo[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [isError, setError] = useState<any>(null);
useEffect(() => {
const singleReq = async () => {
try {
setLoading(true);
const res = await axios.get<Todo[]>(
`https://jsonplaceholder.typicode.com/posts/${id}`,
);
await setData(res.data);
console.log(res.data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
singleReq();
}, [id]);
return (
<div className=' w-full h-screen bg-slate-900 text-neutral-300 p-4'>
<div className='w-full flex justify-center '> Single Post {id}</div>
{loading && <p>...Loading</p>}
{isError && <p> Error in getting post</p>}
<div className='text-2xl'> {data.title}</div>
<div className=' text-xl'> {data.body}</div>
</div>
);
};
export default SinglePOST;
This is the error it was displaying
Property 'title' does not exist on type 'Todo[]'
Property 'body' does not exist on type 'Todo[]'
CodePudding user response:
because your data is a single object but you defined your data as a list of objects.
import { To, useParams } from 'react-router-dom';
import axios from 'axios';
import { useState, useEffect } from 'react';
const SinglePOST = () => {
type Todo = {
title: string;
body: string;
userId: number;
id: number;
};
const { id } = useParams();
const [data, setData] = useState<Todo>();
const [loading, setLoading] = useState<boolean>(false);
const [isError, setError] = useState<any>(null);
useEffect(() => {
const singleReq = async () => {
try {
setLoading(true);
const res = await axios.get<Todo>(
`https://jsonplaceholder.typicode.com/posts/${id}`
);
await setData(res.data);
console.log(res.data);
} catch (err) {
setError(err);
} finally {
setLoading(false);
}
};
singleReq();
}, [id]);
return (
<div className=' w-full h-screen bg-slate-900 text-neutral-300 p-4'>
<div className='w-full flex justify-center '> Single Post {id}</div>
{loading && <p>...Loading</p>}
{isError && <p> Error in getting post</p>}
<div className='text-2xl'> {data?.title}</div>
<div className=' text-xl'> {data?.body}</div>
</div>
);
};
CodePudding user response:
You've set the type to your state as a list of Todo objects, hence the error.
const [data, setData] = useState<Todo[]>([]);
Does your get request return an array of todos? If yes then you need to map through them:
{
data.map((todo, idx) => {
return (
<div key={idx}>
<div className='text-2xl'> {data.title}</div>
<div className=' text-xl'> {data.body}</div>
</div>
)
});
}
If your get request returns a todo object then you need to change the type on your state:
const [data, setData] = useState<Todo>();