useCustom invalidated by useCreate

Is is possibly to get useCustom to be automatically invalidted be a useCreate mutation
8 Replies
kapa.ai
kapa.ai2w ago
Hi @Joe Gaffney. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Yes, it is possible to get a useCustom query to be invalidated by a useCreate mutation in refine. You can achieve this by specifying which queries should be invalidated after the mutation is completed using the invalidates parameter in the mutate method of useCreate. Here is an example of how you can do this:
import { useCreate, useCustom, useQueryClient } from "@refinedev/core";

// Custom query using useCustom
const { data, refetch, isLoading } = useCustom({
url: `${apiUrl}/custom-endpoint/`,
method: 'get',
queryOptions: {
queryKey: ['custom-key'],
},
});

// Create mutation using useCreate
const { mutate } = useCreate({
resource: "products",
});

mutate({
values: {
name: "New Product",
material: "Wood",
},
invalidates: ["custom-key"], // Specify the custom query key to invalidate
});
import { useCreate, useCustom, useQueryClient } from "@refinedev/core";

// Custom query using useCustom
const { data, refetch, isLoading } = useCustom({
url: `${apiUrl}/custom-endpoint/`,
method: 'get',
queryOptions: {
queryKey: ['custom-key'],
},
});

// Create mutation using useCreate
const { mutate } = useCreate({
resource: "products",
});

mutate({
values: {
name: "New Product",
material: "Wood",
},
invalidates: ["custom-key"], // Specify the custom query key to invalidate
});
In this example: 1. The useCustom hook is used to fetch data from a custom endpoint. 2. The useCreate hook is used to create a new product. 3. The invalidates parameter in the mutate method specifies that the custom query with the key custom-key should be invalidated after the mutation is completed. This ensures that the custom query will be refetched after the useCreate mutation runs successfully. For more information, you can refer to the useCreate documentation (https://refine.dev/docs/data/hooks/use-create/#invalidates). If you encounter any issues or need further assistance, feel free to ask! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@422289470487003153> kapa.ai is still learning and improving, please let us know how it did by reacting below
optimistic-gold
optimistic-gold2w ago
@kapa.ai but what could be the pattern to make this useCustom look like a useList what keys would it need
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you. One moment! :books: ---------------------- To make a useCustom query look like a useList query and ensure it uses the same key structure, you need to follow the key structure pattern used by useList. This involves generating a structured key that includes the data provider, resource, action, and parameters. Here is an example of how you can achieve this: 1. Define the key structure: Use the keys method from @refinedev/core to generate the key. 2. Use the generated key in useCustom: Pass the generated key to the queryOptions property of useCustom. 3. Invalidate the query: Use the invalidateQueries method from useQueryClient to invalidate the query when needed. Here is a complete example:
import { useCustom, useQueryClient, keys } from "@refinedev/core";

// Generate the key using the keys method
const generatedKey = keys()
.data("default") // Name of the data provider
.resource("products") // Identifier of the resource
.action("list") // Type of the operation
.params({
filters: [{ field: "title", operator: "contains", value: "test" }]
}) // Parameters of the operation
.get();

// Custom query using useCustom with the generated key
const { data, refetch, isLoading } = useCustom({
url: '/custom-endpoint/',
method: 'get',
queryOptions: {
queryKey: generatedKey,
},
});

// Invalidate the query when needed
const queryClient = useQueryClient();
queryClient.invalidateQueries(generatedKey);
import { useCustom, useQueryClient, keys } from "@refinedev/core";

// Generate the key using the keys method
const generatedKey = keys()
.data("default") // Name of the data provider
.resource("products") // Identifier of the resource
.action("list") // Type of the operation
.params({
filters: [{ field: "title", operator: "contains", value: "test" }]
}) // Parameters of the operation
.get();

// Custom query using useCustom with the generated key
const { data, refetch, isLoading } = useCustom({
url: '/custom-endpoint/',
method: 'get',
queryOptions: {
queryKey: generatedKey,
},
});

// Invalidate the query when needed
const queryClient = useQueryClient();
queryClient.invalidateQueries(generatedKey);
In this example: 1. The keys method is used to generate a structured key for the useCustom query. 2. The useCustom hook is used to fetch data from a custom endpoint, and the generated key is passed to the queryOptions property. 3. The invalidateQueries method from useQueryClient is used to invalidate the query when needed. This approach ensures that the useCustom query uses the same key structure as useList, making it easier to manage and invalidate queries. For more information, you can refer to the Key Structure documentation (https://refine.dev/docs/guides-concepts/general-concepts/#key-structure) and the useCustom documentation (https://refine.dev/docs/data/hooks/use-custom/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@422289470487003153> kapa.ai is still learning and improving, please let us know how it did by reacting below
optimistic-gold
optimistic-gold2w ago
@kapa.ai this was my solution which will still invalidate. Leading for refernce for others import { useApiUrl, useCustom } from "@refinedev/core"; interface UseCustomListProps { resource: string; payload: any; onSuccess?: (data: any) => void; enabled?: boolean; } export function useCustomList({ resource, payload, onSuccess, enabled = true }: UseCustomListProps) { const apiUrl = useApiUrl("default"); const result = useCustom({ url: ${apiUrl}/api/${resource}/query, method: "post", config: { payload: payload }, queryOptions: { enabled: enabled, queryKey: ["data", "default", resource, "list", payload], onSuccess: (data) => { if (onSuccess) { onSuccess(data); } }, }, }); return result; }
kapa.ai
kapa.ai2w ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Your solution for creating a custom hook that mimics the behavior of useList while using useCustom is well-structured and should work effectively for invalidating queries. Here is your solution formatted as Markdown for reference:
import { useApiUrl, useCustom } from "@refinedev/core";

interface UseCustomListProps {
resource: string;
payload: any;
onSuccess?: (data: any) => void;
enabled?: boolean;
}

export function useCustomList({ resource, payload, onSuccess, enabled = true }: UseCustomListProps) {
const apiUrl = useApiUrl("default");

const result = useCustom({
url: `${apiUrl}/api/${resource}/query`,
method: "post",
config: { payload: payload },
queryOptions: {
enabled: enabled,
queryKey: ["data", "default", resource, "list", payload],
onSuccess: (data) => {
if (onSuccess) {
onSuccess(data);
}
},
},
});

return result;
}
import { useApiUrl, useCustom } from "@refinedev/core";

interface UseCustomListProps {
resource: string;
payload: any;
onSuccess?: (data: any) => void;
enabled?: boolean;
}

export function useCustomList({ resource, payload, onSuccess, enabled = true }: UseCustomListProps) {
const apiUrl = useApiUrl("default");

const result = useCustom({
url: `${apiUrl}/api/${resource}/query`,
method: "post",
config: { payload: payload },
queryOptions: {
enabled: enabled,
queryKey: ["data", "default", resource, "list", payload],
onSuccess: (data) => {
if (onSuccess) {
onSuccess(data);
}
},
},
});

return result;
}
Explanation 1. Parameters: - resource: The resource endpoint you want to query. - payload: The payload to be sent with the request. - onSuccess: Optional callback function to be executed on successful data retrieval. - enabled: Boolean to enable or disable the query. 2. API URL: - The useApiUrl hook is used to get the base URL of the API endpoint. 3. useCustom Hook: - The useCustom hook is used to send a custom query request. - The url is constructed using the apiUrl and the resource. - The method is set to "post". - The config includes the payload. - The queryOptions include: - enabled: To enable or disable the query. - queryKey: A unique key for the query, structured similarly to useList. - onSuccess: A callback function to handle successful data retrieval. This approach ensures that your custom hook behaves similarly to useList and can be invalidated appropriately. For more information, you can refer to the useCustom documentation (https://refine.dev/docs/data/hooks/use-custom/) and the useApiUrl documentation (https://refine.dev/docs/api-reference/core/hooks/data/useApiUrl/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@422289470487003153> kapa.ai is still learning and improving, please let us know how it did by reacting below