reactjstypescriptreact-query

React Query fetches data from backend but results undefined


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:

React Query Results

Console.log for {data} data log

Console.log for {data?.results}

console.log for results


Solution

  • 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.