stormy-gold•5w ago
how to use antd notification for custom apis in page
how to use antd notification for custom apis in page
55 Replies
Hi @jakshire01. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
To use Ant Design notifications for custom API calls in a Refine page, you should:
1. Set up Refine with Ant Design's notification provider
Make sure your app is wrapped with the Ant Design theme and the
The
If you use Refine's data hooks like
- Set up
Make sure your app is wrapped with the Ant Design theme and the
useNotificationProvider from @refinedev/antd is passed to the notificationProvider prop of <Refine />:
Ant Design Introduction - Notifications
2. Use the useNotification hook in your pageThe
useNotification hook gives you access to the open and close methods for notifications. You can call these methods after your custom API logic:
Built-in Notification Providers - Ant Design Example
3. (Optional) Customize notifications in data hooksIf you use Refine's data hooks like
useCustomMutation for your API, you can pass successNotification and errorNotification props to customize notifications:
useCustomMutation - successNotification and errorNotification
Summary:- Set up
notificationProvider={useNotificationProvider} in <Refine />.
- Use useNotification in your page to show notifications after custom API calls.
- Or, use successNotification/errorNotification in Refine data hooks for automatic notifications.
This approach ensures your notifications are consistent with Ant Design and fully integrated with Refine.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4w ago
@kapa.ai
can i enable disable pages based on some setting
so that i have a saas product
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, you can enable or disable pages in your Refine app based on settings, which is a common requirement for SaaS products. Refine provides flexible access control mechanisms that allow you to control access to resources (pages) dynamically.
You can achieve this by using the Access Control Provider. The
can method in your accessControlProvider can check any condition—including feature flags, tenant settings, or user roles—and return whether access is allowed. If access is denied, you can hide or disable navigation links, buttons, or even entire pages.
For example, you can define your accessControlProvider like this:
Then, use the <CanAccess /> component or the useCan hook to conditionally render pages or navigation items:
Or, for navigation:
This approach allows you to implement feature gating and page-level access control, which is essential for SaaS products with different plans or tenant-based features. Refine's access control is designed to be flexible and can be integrated with any logic you need for your SaaS use case Authorization Guide Access Control Provider Usage.
Note: The actual logic for checking settings or feature flags is up to you and can be as simple or complex as your SaaS product requires. Refine provides the infrastructure to enforce these checks throughout your app.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2w ago
@kapa.ai
for my custom apis iam going to call on my form pages or other pages
how can i trigger the toast message in the best possible way
Let me check the knowledge base for you again. One moment! :books:
----------------------
To trigger toast messages (notifications) for your custom API calls on form pages or other pages in a Refine app, the best practice is to use the useNotification hook provided by Refine. This hook gives you access to open and close methods, which you can call after your API logic to show success or error notifications.
Here’s how you can do it:
1. Import and use the useNotification hook in your component:
This approach ensures your notifications are consistent with the rest of your Refine app and leverages the notification provider you have configured (e.g., Ant Design, React Toastify, etc.) useNotification documentation Built-in Notification Providers Example.
Summary:
- Use the useNotification hook in your page or form. - Call open with the appropriate type, message, and description after your custom API call. - This method works seamlessly with your configured notification provider and is the recommended way in Refine. If you use Refine’s data hooks (like useCustomMutation), you can also use the successNotification and errorNotification props for automatic notifications, but for direct custom API calls, useNotification is the best approach Customizing Notifications. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
- Use the useNotification hook in your page or form. - Call open with the appropriate type, message, and description after your custom API call. - This method works seamlessly with your configured notification provider and is the recommended way in Refine. If you use Refine’s data hooks (like useCustomMutation), you can also use the successNotification and errorNotification props for automatic notifications, but for direct custom API calls, useNotification is the best approach Customizing Notifications. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2w ago
can i make generic methods so that on success and failure i can call the toast messages
@kapa.ai
can i make generic methods so that on success and failure i can call the toast messages
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, you can create generic methods to trigger toast messages (notifications) for success and failure in your Refine app. The recommended way is to use the
- Yes, you can make generic methods for success and error toasts. - Use the
useNotification hook, which provides the open method for showing notifications. You can wrap this in your own utility functions for reuse across your app.
Here’s how you can do it:
You can then use these helpers in any component:
This approach is fully compatible with Refine’s notification system and works with any notification provider you have configured (e.g., Ant Design, React Toastify, etc.) useNotification documentation Built-in Notification Providers Example.
Summary:- Yes, you can make generic methods for success and error toasts. - Use the
useNotification hook and wrap it in your own helpers for reuse.
- This is a recommended and supported pattern in Refine.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2w ago
@kapa.ai
{services.map((service, index) => { return ( <Fragment key={index}> <Col xs={{span: 7}} className={styles.serviceRowColumn} > <Select {...selectPropsInventory} placeholder="Name" showSearch={true} onChange={(e) => { setServices((prev) => prev.map((item, i) => i === index ? {...item, name: e.value} : item ) ); }} /> </Col> <Col xs={{span: 5}} className={styles.serviceRowColumn} > <InputNumber addonBefore={selectedCurrencySymbol} style={{width: "100%"}} placeholder="Unit Price" min={0} precision={2} value={service.unitPrice} onChange={(value) => { handleServiceNumbersChange( index, "unitPrice", value 0 ); }} /> </Col> <Col xs={{span: 4}} className={styles.serviceRowColumn} > <InputNumber style={{width: "100%"}} placeholder="Quantity" min={0} precision={2} value={service.quantity} onChange={(value) => { handleServiceNumbersChange( index, "quantity", value 0 ); }} /> </Col> <Col xs={{span: 4}} className={styles.serviceRowColumn} > <InputNumber addonAfter="%" style={{width: "100%"}} placeholder="Discount Percentage" min={0} precision={2} max={100} value={service.item_discount_percentage} onChange={(value) => { handleServiceNumbersChange( index, "item_discount_percentage", value || 0 ); }} /> </Col>
these are in my create invoice page i want to be able to automatically enter the price, discount field when the dropdown value of item name is selected the data is coming from inventory this is how inventory data looks like
export type InventoryItem = { id: string; item_code: string; item_name: string; description: string; category: string; // e.g., "Electronics", "Consumables" unit: string; // e.g., pcs, kg, box sku: string; barcode: string; is_service: boolean; // Pricing cost_price: number; selling_price: number; tax_rate: number; // % discount_rate: number; current_stock: number; userId: string; }
Let me check the knowledge base for you again. One moment! :books:
----------------------
To automatically populate the price and discount fields when an item is selected from the dropdown in your create invoice page, you need to update the corresponding fields in your
Use the
When the user selects an item, use the selected value (typically the
Update the
- The exact structure of
services state based on the selected inventory item's data.
How to approach this in Refine (with Ant Design):
1. Fetch inventory data for the Select optionsUse the
useSelect hook to fetch inventory items and provide them as options to your <Select /> component. The useSelect hook will give you access to the full data of each inventory item, not just the label and value, which is essential for this use case Ant Design useSelect documentation.
2. On item selection, find the selected inventory itemWhen the user selects an item, use the selected value (typically the
id) to find the full inventory item object from your options or from the fetched data.
3. Update the corresponding service rowUpdate the
unitPrice and item_discount_percentage fields in your services state with the selling_price and discount_rate from the selected inventory item.
Example Implementation:
Assuming you have fetched your inventory data and have access to the full list of items (e.g., via selectPropsInventory.options or a separate state):
Key Points:
- The onChange handler uses the selected value to find the full inventory item.
- It then updates the services state for the current row, setting unitPrice and item_discount_percentage from the inventory data.
Note:- The exact structure of
selectPropsInventory.options depends on how you set up your useSelect hook. If you customize the options, ensure each option includes the full inventory item data (e.g., { label, value, data: inventoryItem }).
- This pattern is fully compatible with Refine and Ant Design, and is a common approach for handling dependent form fields Ant Design useSelect FAQ.
If you need to customize the options structure, you can manually map the fetched data as shown in the documentation:
Then pass these options to your <Select />.
---
This approach ensures that when a user selects an item, the related fields (price, discount) are automatically filled based on your inventory data, using patterns recommended in the Refine documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2w ago
@kapa.ai
give me more details for above solution
inventoryData where its coming from
give the code
Let me check the knowledge base for you again. One moment! :books:
----------------------
Certainly! Here’s a detailed explanation and code example for your scenario, based on Refine and Ant Design’s recommended patterns.
1. Where does
To access the full inventory item, you need to fetch the data separately or customize the options. #### b. Fetch the full inventory list (for lookup) You can use a data hook like
- Use
inventoryData come from?
In Refine, you typically use the useSelect hook to fetch data for a <Select /> component. This hook fetches the data from your resource (in this case, "inventory") and provides it as options for the select input. The options can be customized to include the full inventory item data, which you’ll need to auto-fill other fields when an item is selected.
2. How to set up and use the data
#### a. Fetch inventory data with useSelect
By default, selectProps.options will be an array of objects like { label, value }.To access the full inventory item, you need to fetch the data separately or customize the options. #### b. Fetch the full inventory list (for lookup) You can use a data hook like
useList to fetch all inventory items:
Now, inventoryData is an array of your full inventory items.
#### c. Update fields on selection
When an item is selected, find the full inventory item by its id and update your services state accordingly.
3. Full Example
---
Summary:- Use
useSelect for select options and useList to get the full inventory data.
- On selection, find the full item in inventoryData and update your service row fields.
- This approach is fully compatible with Refine and Ant Design best practices see useSelect documentation.
If you need further customization, you can also manually build your options array to include the full item data as shown in the documentation see FAQ: Can I create the options manually?.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2w ago
@kapa.ai
okay now that dropdown is coming now how do i map to other components so that selling price and discount comes up
Let me check the knowledge base for you again. One moment! :books:
----------------------
To map the selected dropdown value to other components (so that selling price and discount fields are automatically filled), you need to:
1. Fetch the full inventory data (so you have access to selling price and discount for each item).
2. On dropdown selection, find the selected inventory item by its ID.
3. Update your form state (e.g., the
services array) with the corresponding selling_price and discount_rate for the selected item.
This pattern is supported and recommended in Refine. The documentation shows that you can manually create options for the <Select /> and, upon selection, use the selected value to find the full item and update other fields accordingly see FAQ: Can I create the options manually?.
Example Approach:
- The onChange handler uses the selected value to find the full inventory item.
- It then updates the services state for the current row, setting unitPrice and item_discount_percentage from the inventory data.
This approach is fully compatible with Refine and Ant Design, and is a common way to handle dependent form fields see useSelect FAQ.
If you need to customize the options structure, you can manually map the fetched data as shown in the documentation, ensuring each option includes the full inventory item data for easy lookup on selection.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•7d ago
@kapa.ai
Let me check the knowledge base for you again. One moment! :books:
Sorry @jakshire01, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:
Perhaps try again in 15mins?
stormy-goldOP•7d ago
@kapa.ai
my antdnotifications are blinking twice before showing up its not smooth
useNotificationProvider,
ThemedLayoutV2,
ErrorComponent,
AuthPage,
} from "@refinedev/antd";
Let me check the knowledge base for you again. One moment! :books:
----------------------
The issue of Ant Design notifications "blinking twice" or appearing multiple times before settling is a known problem that has been reported by Refine users. This behavior is often related to how React's
The blinking or duplicate notification issue is most likely due to React's
<StrictMode> works in development, which intentionally double-invokes certain lifecycle methods (including effects) to help identify side effects. As a result, API calls and notifications may be triggered twice in development mode, causing the blinking or duplicate notifications you observe.
Key points from the knowledge sources:
- This is expected behavior in development due to React's <StrictMode>. Refine's FAQ addresses this, explaining that API calls (and thus notifications) may trigger twice in development, but this does not happen in production builds Why are API calls triggering twice? <https://github.com/refinedev/refine/issues/4236.>
- If you are seeing this in production, it may be due to how notification keys are managed or how your notification logic is implemented. There have been reports of duplicate notifications when keys are not unique or when error handling triggers multiple notifications <https://github.com/refinedev/refine/issues/6269> <https://github.com/refinedev/refine/issues/3392.>
What you can do:
- Check if the issue occurs only in development: If so, it is likely due to <StrictMode> and will not affect your production users.
- Ensure unique notification keys: If you trigger multiple notifications in quick succession, make sure each has a unique key to avoid unexpected behavior.
- Review your notification logic: If you are using function-based notification callbacks (like errorNotification as a function), ensure they are not being re-executed unnecessarily, as this can cause infinite or repeated notifications <https://github.com/refinedev/refine/issues/6983.>
Summary:The blinking or duplicate notification issue is most likely due to React's
<StrictMode> in development, which is expected and not present in production. If you see this in production, review your notification keys and logic for uniqueness and proper effect dependencies.
If you need more specific troubleshooting, please provide a minimal reproducible example or clarify if this occurs in production or only during development.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
on one of my list.tsx page where it has table for invoices data
i want to have a search range filter to filter data between the dates
Let me check the knowledge base for you again. One moment! :books:
----------------------
To add a date range filter to your invoices list page in Refine with Ant Design, you can use the
- Add a
<DatePicker.RangePicker /> component in a filter form and map its values to your table's filters. Here’s a step-by-step approach based on the knowledge sources:
1. Add a Filter Form with RangePicker
Use the useTable hook to get searchFormProps, and include a RangePicker in your filter form:
Table Search Example
2. Map the RangePicker Values to Filters
In your useTable hook, use the onSearch option to map the selected date range to gte and lte filters for your invoice date field:
Table Search Mapping Example
---
Summary:- Add a
<RangePicker /> to your filter form.
- Use onSearch in useTable to map the selected range to gte and lte filters for your date field.
- This approach is fully supported and demonstrated in Refine’s documentation.
If you need a column filter (in the table header), you can use <FilterDropdown /> with a RangePicker and the rangePickerFilterMapper utility as shown in the Ant Design FilterDropdown documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
why do i get this on rangepicker
chunk-6W5FFVKH.js?v=f27d8eb8:19413 Uncaught TypeError: date4.isValid is not a function
Let me check the knowledge base for you again. One moment! :books:
----------------------
The error
You are getting this error because the value passed to
Uncaught TypeError: date4.isValid is not a function when using Ant Design's RangePicker typically occurs when the value passed to the RangePicker is not a Dayjs (or Moment) object, but rather a plain string or an object that does not have the isValid method.
According to the knowledge sources, this issue often arises when filter values are restored from the URL (for example, when using syncWithLocation or after a page refresh). In such cases, the values are parsed as strings, not as Dayjs objects, which leads to this error when the RangePicker expects Dayjs objects rangePickerFilterMapper documentation.
How to fix:
You need to map the string values back to Dayjs objects before passing them to the RangePicker. Refine provides a utility function called rangePickerFilterMapper for this purpose. When the event is "value", it converts string values to Dayjs objects for use in the RangePicker:
This ensures that when the filter value is restored from the URL (as a string), it is converted back to a Dayjs object before being passed to the RangePicker, preventing the isValid error rangePickerFilterMapper explanation.
Summary:You are getting this error because the value passed to
RangePicker is not a Dayjs object. Use the rangePickerFilterMapper utility to convert string values to Dayjs objects before passing them to the RangePicker to resolve this issue.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
how do i update this according to above solution
<Space>
<Form layout="vertical" {...searchFormProps}>
{/<Form.Item label="Search" name="q">/}
{/* <Input placeholder="ID, Name, etc." prefix={<SearchOutlined/>}/>/}
{/</Form.Item>*/}
<Form.Item label="Invoice Date" name="invoiceDate">
<RangePicker
/>
</Form.Item>
<Form.Item>
Let me check the knowledge base for you again. One moment! :books:
----------------------
To update your code so that the
If you are using URL sync (
- Map the selected date range to
<RangePicker /> works correctly with Refine's filtering and avoids issues like the isValid error, you should ensure that:
1. The values passed to RangePicker are always Dayjs objects (not strings).
2. You map the selected range to gte and lte filters in your useTable's onSearch function.
Here’s how you can do it, based on the knowledge sources:
1. Map the RangePicker values in onSearch:
See Table Search Example
2. Use the RangePicker in your form:
Important:If you are using URL sync (
syncWithLocation), make sure that when restoring values from the URL, you convert them from strings to Dayjs objects before passing them to the RangePicker. This is handled automatically by Refine's form system in most cases, but if you encounter issues, refer to the rangePickerFilterMapper utility for custom mapping.
---
Summary:- Map the selected date range to
gte and lte filters in onSearch.
- Ensure the value for RangePicker is always a Dayjs object.
- This approach is directly supported and recommended in Refine's documentation.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
in the above solutiioln i see dayjs imported but not being used
import { Dayjs } from "dayjs";
Let me check the knowledge base for you again. One moment! :books:
----------------------
You're correct—while the code example imports
If you are not using
Dayjs from "dayjs", it does not use the Dayjs variable directly in the code. This is a common pattern when you want to type variables or function parameters as Dayjs, but in the provided example, the type is not explicitly used.
In the context of Refine and Ant Design, the RangePicker component returns an array of Dayjs objects, and you typically use their methods (like .toISOString()) in your onSearch mapping. The import is only necessary if you are explicitly typing variables or function parameters as Dayjs. If you are not using it for typing, you can safely remove the import.
This pattern is also seen in the official Refine documentation, where Dayjs is imported for typing the filter variables, but if you do not use it for types, the import is not required Table Search Example.
Summary:If you are not using
Dayjs for typing or directly in your code, you can remove the import. Its presence in the example is not required unless you are using it for TypeScript type annotations.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
should this only be used in filterdropdown
rangePickerFilterMapper utility
Let me check the knowledge base for you again. One moment! :books:
----------------------
The
Based on the documentation,
rangePickerFilterMapper utility is specifically documented for use with the <FilterDropdown /> component in Ant Design tables within Refine. Its main purpose is to correctly map the values between Dayjs objects (used by Ant Design's <DatePicker.RangePicker />) and the string format expected by Refine's data provider and URL synchronization. This ensures that when filter values are restored from the URL (as strings), they are converted back to Dayjs objects for the RangePicker, and vice versa when the user changes the value rangePickerFilterMapper documentation.
There is no explicit mention in the knowledge sources about using rangePickerFilterMapper outside of <FilterDropdown />. The examples and explanations focus on its use within the context of table column filters, not in standalone forms or other filter mechanisms.
In summary:Based on the documentation,
rangePickerFilterMapper is intended for use in <FilterDropdown /> scenarios. There is no information in the knowledge sources about its use outside of this context, so its use should be limited to filter dropdowns in Ant Design tables within Refine.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
this is working
filterDropdown={(props) => (
<FilterDropdown {...props} mapValue={(selectedKeys, event) => {
return rangePickerFilterMapper(selectedKeys, event);
}}>
<DatePicker.RangePicker />
</FilterDropdown>
)}
render={(_, record: Invoice) => {
return (
<DateField value={record.invoiceDate} format="D MMM YYYY"/>
);
}}
/>
but iam getting same name filters in the payload
invoice.invoiceDate
2025-08-31T18:30:00.000Z
invoice.invoiceDate
2025-09-29T18:30:00.000Z
Let me check the knowledge base for you again. One moment! :books:
----------------------
The behavior you're seeing—multiple filters with the same field name (
- Multiple filters with the same field name but different operators are normal in Refine's filter payload. - If your backend requires a different format, map or merge these filters in your data provider before sending the request. If you need an example of how to handle this in a data provider, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
invoice.invoiceDate) in the payload—is expected when using separate filters for a date range (e.g., one for gte and one for lte). Refine's filtering system sends each filter as a separate object, even if they target the same field, because each represents a different operator (greater than or equal, less than or equal, etc.) Table Search Mapping Example.
For example, the payload might look like:
This is the intended structure for Refine's data provider, as it allows the backend to interpret the range as "between these two dates." The field name is repeated, but the operator distinguishes the filters.
If your backend expects a different structure (such as a single object with both values), you will need to handle this mapping in your custom data provider. Refine itself does not merge these filters into a single object; it leaves that responsibility to the data provider implementation Handling Filters in a Data Provider.
Summary:- Multiple filters with the same field name but different operators are normal in Refine's filter payload. - If your backend requires a different format, map or merge these filters in your data provider before sending the request. If you need an example of how to handle this in a data provider, let me know! ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
no payload looks like this
all the req params
_end=10&_order=desc&_sort=updatedAt&_start=0&invoice.invoiceDate=2025-08-31T18%3A30%3A00.000Z&invoice.invoiceDate=2025-09-29T18%3A30%3A00.000Z
Let me check the knowledge base for you again. One moment! :books:
----------------------
The behavior you are seeing—where the request parameters include multiple
You need to update your data provider to map filter operators to the query string keys. For example, instead of: You should generate: The documentation provides a mapping function for this purpose: Data Provider Interface Example Summary:
- The current query string does not include operators, which is why you see duplicate keys. - To include operators (like
invoice.invoiceDate entries in the query string, like:
—is a result of how Refine's default data provider example serializes filters. When there are multiple filters for the same field (such as for a date range), it pushes both values into the query string with the same key, but without including the operator (e.g., gte, lte). This can be problematic for backends that expect operators to be specified.
The knowledge sources show that, by default, the simple REST data provider example in Refine does not handle operators in the query string; it just appends field=value for each filter Listing Data Example. For more advanced use cases, you are expected to customize your data provider to include operators in the query string, such as invoice.invoiceDate_gte=... and invoice.invoiceDate_lte=... Data Provider Interface Example.
To fix this:You need to update your data provider to map filter operators to the query string keys. For example, instead of: You should generate: The documentation provides a mapping function for this purpose: Data Provider Interface Example Summary:
- The current query string does not include operators, which is why you see duplicate keys. - To include operators (like
_gte, _lte), customize your data provider as shown in the documentation.
- This is a common step when adapting Refine to work with different backend APIs.
If you follow the advanced data provider example, your filters will be serialized correctly for most REST APIs.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•4d ago
@kapa.ai
cant i do any modifications here
filterDropdown={(props) => (
<FilterDropdown {...props} mapValue={(selectedKeys, event) => {
return rangePickerFilterMapper(selectedKeys, event);
}}>
<DatePicker.RangePicker />
</FilterDropdown>
)}
render={(_, record: Invoice) => {
return (
<DateField value={record.invoiceDate} format="D MMM YYYY"/>
);
}}
/>
Let me check the knowledge base for you again. One moment! :books:
----------------------
Based on the knowledge sources, modifications to how filter operators are mapped to the query string (e.g., appending
You cannot modify the filter operator mapping in the
_gte or _lte to the field name) cannot be handled directly in the filterDropdown or its mapValue property. The filterDropdown and rangePickerFilterMapper are responsible for mapping UI values (like Dayjs objects and strings) for the filter component, not for how the filter is serialized or sent to the backend.
The actual mapping of filter operators to query string parameters (such as converting two invoice.invoiceDate filters into invoice.invoiceDate_gte and invoice.invoiceDate_lte) must be handled in your data provider. This is explicitly described in the documentation and issues, which show that the data provider is responsible for serializing filters with their operators for the backend API, not the UI components or filter dropdowns Data Provider Interface Example.
In summary:You cannot modify the filter operator mapping in the
filterDropdown or mapValue. You must implement this logic in your data provider, as shown in the advanced data provider examples in the knowledge sources. The UI components only handle value selection and conversion, not query serialization.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2d ago
@kapa.ai
i used this in my pdflayout
const {data} = useList<MyOrgProfile>({
resource: "myorgprofile",
});
i get this error
chunk-6W5FFVKH.js?v=4560e3de:9129 Uncaught Error: No QueryClient set, use QueryClientProvider to set one
at useQueryClient (chunk-AKBUTMJC.js?v=4560e3de:6305:11)
at useInvalidateAuthStore (chunk-AKBUTMJC.js?v=4560e3de:9065:11)
at useLogout (chunk-AKBUTMJC.js?v=4560e3de:9071:11)
at useOnError (chunk-AKBUTMJC.js?v=4560e3de:9163:158)
at useList (chunk-AKBUTMJC.js?v=4560e3de:9197:109)
at PdfLayout (pdfLayout.tsx:68:20)
Let me check the knowledge base for you again. One moment! :books:
----------------------
The error
This error means your component is not inside the
No QueryClient set, use QueryClientProvider to set one occurs because the useList hook (and other Refine data hooks) rely on React Query's context, which is provided by a QueryClientProvider. In a typical Refine application, this provider is automatically set up for you when you wrap your app with the <Refine /> component.
However, if you use useList (or any Refine data hook) outside of the <Refine /> context—such as in a custom PDF layout or a component that is not a child of <Refine />—the required context is missing, and you get this error.
How to fix:
- Make sure that your PdfLayout component (and any component using Refine hooks) is rendered within the <Refine /> component tree, so the React Query context is available.
- Do not wrap your component with a separate QueryClientProvider, as Refine already handles this internally. Creating a second provider can cause unexpected bugs see related issue.
Summary:This error means your component is not inside the
<Refine /> context. Ensure that all components using Refine hooks are children of <Refine /> so the necessary providers (including React Query's QueryClientProvider) are available see usage with existing projects.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
stormy-goldOP•2d ago
@kapa.ai
im using inside this
export const PdfLayout: React.FC<PdfProps> = ({record}) => {
Let me check the knowledge base for you again. One moment! :books:
----------------------
The error
Your
No QueryClient set, use QueryClientProvider to set one occurs because your PdfLayout component is using the useList hook from Refine, which depends on the React Query context provided by QueryClientProvider. In a standard Refine application, this context is set up automatically when your component is rendered as a child of the <Refine /> component.
If you use useList inside PdfLayout and PdfLayout is not rendered within the <Refine /> component tree, the required context is missing, resulting in this error. This is a common issue when trying to use Refine hooks in components that are rendered outside of the main app context, such as in custom layouts or utility components see related issue.
How to resolve:
- Ensure that your PdfLayout component is rendered as a descendant of the <Refine /> component so that the React Query context is available.
- Do not wrap your component with a separate QueryClientProvider, as Refine already handles this internally, and doing so can cause additional issues see related issue.
If you need to use data fetching in a context where the Refine providers are not available (such as server-side PDF generation or outside the React tree), you will need to fetch the data manually (e.g., using fetch or axios) instead of using Refine hooks.
Summary:Your
PdfLayout must be rendered within the <Refine /> context to use useList and other Refine hooks. If that's not possible, use manual data fetching in that component. This is a documented limitation and expected behavior in Refine.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@418995770205929473> Kapa.ai is still learning and improving, please let me know how I did by reacting below.