Reputation: 1222
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
Upvotes: 1
Views: 12681
Reputation: 384
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:
useOrderItemsForCardsInList()
. Don’t call React Hooks inside loops, conditions, or nested functions. See React hooks rules.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.UseQueryResult<OrderItemsResult>
to useOrderItemsForCardsInList()
function.getOrderItemsForCardsInList()
, it should not be response.json()
because that would be Promise
, not actual data. Instead use await response.json()
.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 (
...
);
}
Upvotes: 0
Reputation: 29056
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:
any
because fetch
is untyped, so even though you are using TypeScript, you won't get any typesafety that way.Upvotes: 6