1

I am using react-query in my TS project:

useOrderItemsForCardsInList.ts:

import { getToken } from '../../tokens/getToken';
import { basePath } from '../../config/basePath';
import { getTokenAuthHeaders } from '../../functions/sharedHeaders';
import { useQuery } from 'react-query';

async function getOrderItemsForCardsInList(listID: string) {
    const token = await getToken();
    const response = await fetch(`${basePath}/lists/${listID}/order_items/`, {
        method: 'GET',
        headers: getTokenAuthHeaders(token)
    });

    return response.json();
}

export default function useOrderItemsForCardsInList(listID: string) {
    if (listID != null) {
        return useQuery(['list', listID], () => {
            return getOrderItemsForCardsInList(listID);
        });
    }
}

I use my query result over here:

import { useCardsForList } from '../../hooks/Cards/useCardsForList';
import useOrderItemsForCardsInList from '../../hooks/Lists/useOrderItemsForCardsInList';
import usePaginateCardsInList from '../../hooks/Cards/usePaginateCardsInList';

export default function CardsListFetch({ listID }: { listID: string }) {
    const { isLoading, isError, error, data } = useCardsForList(listID);
    const { orderItems } = useOrderItemsForCardsInList(listID);
    const pagesArray = usePaginateCardsInList(orderItems, data);

    return (
        ...
    );
}

However, on my const { orderItems } = useOrderItemsForCardsInList(listID); line, I get the following error:

Property 'orderItems' does not exist on type 'UseQueryResult<any, unknown> | undefined'.

How can I resolve this? I don't really know how to consume the result of my query on Typescript, any help is be appreciated

2 Answers 2

6

The property on useQuery that you need to consume where you find your data is called data, so it should be:

const { data } = useOrderItemsForCardsInList(listID);

if that data has a property called orderItems, you can access it from there.

However, two things I'm seeing in your code:

  1. a conditional hook call of useQuery (which is forbidden in React)
  2. your queryFn returns any because fetch is untyped, so even though you are using TypeScript, you won't get any typesafety that way.
Sign up to request clarification or add additional context in comments.

2 Comments

The first thing I get why is the case, and in fact, it made the error dissapear alongside the const { data }, however, how can I solve the second point? Sorry, I'm still new to TS
You need to add a return type to the getOrderItemsForCardsInList function
0

If you are using React with react-query, I suggest you install this devDependency called: "@types/react-query". When using VS Code or any other smart text editor that will help, because it will help you with type suggestions.

npm i --save-dev @types/react-query

Then go to your code and fix couple things:

  • remove condition from useOrderItemsForCardsInList(). Don’t call React Hooks inside loops, conditions, or nested functions. See React hooks rules.
  • import UseCategoryResult and define interface for your return object. You can call it OrderItemsResult or similar. Add type OrderType with the fields of the order object or just use orderItems: any for now.
  • Add return type UseQueryResult<OrderItemsResult> to useOrderItemsForCardsInList() function.
  • Fix return value of getOrderItemsForCardsInList(), it should not be response.json() because that would be Promise, not actual data. Instead use await response.json().
  • So your function useOrderItemsForCardsInList() will return UseQueryResult which has properties like isLoading, error and data. In your second code snipper, you already use data in one place, so instead rename data to orderData and make sure you define default orderItems to empty array to avoid issues: data: orderData = {orderItems: []}

useOrderItemsForCardsInList.ts:

import { getToken } from '../../tokens/getToken';
import { basePath } from '../../config/basePath';
import { getTokenAuthHeaders } from '../../functions/sharedHeaders';
import { useQuery, UseCategoryResult } from 'react-query';

type OrderType = {
    id: string;
    name: string;
    // whatever fields you have.
}

interface OrderItemsResult {
  orderItems: OrderType[],
}

async function getOrderItemsForCardsInList(listID: string) {
    const token = await getToken();
    const response = await fetch(`${basePath}/lists/${listID}/order_items/`, {
        method: 'GET',
        headers: getTokenAuthHeaders(token)
    });
    const data = await response.json();
    return data;
}

export default function useOrderItemsForCardsInList(listID: string): UseQueryResult<OrderItemsResult> {
    return useQuery(['list', listID], () => {
        return getOrderItemsForCardsInList(listID);
    });
}

Use your query result:

import { useCardsForList } from '../../hooks/Cards/useCardsForList';
import useOrderItemsForCardsInList from '../../hooks/Lists/useOrderItemsForCardsInList';
import usePaginateCardsInList from '../../hooks/Cards/usePaginateCardsInList';

export default function CardsListFetch({ listID }: { listID: string }) {
    const { isLoading, isError, error, data } = useCardsForList(listID);
    const { data: orderData = { orderItems: []}} = useOrderItemsForCardsInList(listID);
    const pagesArray = usePaginateCardsInList(orderItems, data);

    return (
        ...
    );
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.