I'm new to react and typescript, but I just finished a course. In the course I was able to access data in the same way I am trying to in my own project but I'm not able to display any data. My react query functions are fetching data because I can see the data response in react query devtools, but my data.results are undefined when I try to map them. Here is my code:
service/apiClient.ts (Service)
import axios, {AxiosRequestConfig} from "axios";
export interface FetchResponse<T> {
count: number;
results: T[];
}
const axiosInstance = axios.create({
baseURL: 'http://127.0.0.1:8000/api',
})
class APIClient<T>{
endpoint: string;
constructor(endpoint: string){
this.endpoint = endpoint;
}
getAll = (config: AxiosRequestConfig) => {
return axiosInstance
.get<FetchResponse<T>>(this.endpoint, config)
.then(res=>res.data)
}
get = (id: number | string) => {
return axiosInstance
.get<T>(this.endpoint + '/' + id )
.then(res => res.data)
}
}
export default APIClient
hooks/useMaterials.ts (Hook)
import { useQuery } from "@tanstack/react-query";
import ms from 'ms';
import Material from "../entities/Material";
import APIClient from "../services/apiClient";
const apiClient = new APIClient<Material>('/materials')
const useMaterials = () =>
useQuery({
queryKey: ['materials'],
queryFn: apiClient.getAll,
staleTime: ms('1m')
})
export default useMaterials
components/MaterialList.tsx (Component)
import {
Spinner,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
} from "@chakra-ui/react";
import useMaterials from "../hooks/useMaterials";
const MaterialList = () => {
const { data, isLoading, error } = useMaterials();
if (error) return null;
if (isLoading) return <Spinner />;
return (
<>
<TableContainer>
<Table variant="striped" colorScheme="#E43D12">
<Thead>
<Tr>
<Th>Title</Th>
<Th>Qty</Th>
<Th>Action</Th>
</Tr>
</Thead>
<Tbody>
{data?.results?.map((material) => (
<Tr key={material.id}>
<Td>{material.title}</Td>
<Td>{material.qty}</Td>
<Td></Td>
</Tr>
))}
</Tbody>
</Table>
</TableContainer>
</>
);
};
export default MaterialList;
entities/Material.ts (Interface)
export default interface Material {
id: number;
title: string;
slug: string;
qty: number;
}
Lastly here is a screenshot of the response:
Console.log for {data?.results}
Try to console
console.log({data, isLoading, error})
Check which properties are in data. If results exist, it should definitely map. Also see error if there is any error.
But first you have to check this
getAll = (config: AxiosRequestConfig) => {
return axiosInstance
.get<FetchResponse<T>>(this.endpoint, config)
.then(res=>res.data)
}
And assign appropriate response type that return from response. And change type accordingly.