robust-apricot•13h ago
add if don't exist
Can i do something like looking for elements in the api, if the response is empty array i update and add element to the api. using Strapi
17 Replies
Hi @SetiZ. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:
----------------------
Based on the provided knowledge sources, Refine does not offer a built-in, single-step method to "update if exists, otherwise add" (commonly known as "upsert") for Strapi or other data providers. The standard approach in Refine is to:
1. Query for the element using a data hook like
You can implement "update if exists, otherwise add" logic in Refine by first querying for the element, then conditionally calling either
useOne, useList, or a custom query.
2. Check if the response is empty (i.e., the element does not exist).
3. If empty, create the element using useCreate.
4. If found, update the element using useUpdate.
Here’s a conceptual example of how you might implement this logic in a React component using Refine hooks:
Important notes:
- You must first fetch the data to determine existence.
- Strapi and Refine do not provide an atomic "upsert" operation out of the box.
- This approach may have race conditions in highly concurrent environments.
If you need true atomic upsert, you would have to implement a custom endpoint in your Strapi backend.
Summary:You can implement "update if exists, otherwise add" logic in Refine by first querying for the element, then conditionally calling either
useUpdate or useCreate based on whether the element exists. There is no built-in upsert method in Refine or the Strapi data provider according to the current documentation and knowledge sources provided.
See data hooks and update example
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
robust-apricotOP•13h ago
@kapa.ai no update, just create a new line. also need to call an external api to get the data to insert
Let me check the knowledge base for you again. One moment! :books:
----------------------
You can implement the logic you described—fetching data from an external API, checking if it exists in your Strapi backend, and creating a new record if it does not exist—using Refine's data hooks. However, Refine does not provide a built-in, single-step method for this; you need to orchestrate the steps manually in your component logic.
Here’s how you can approach it, based on the knowledge sources:
1. Call the external API using your preferred method (e.g.,
See useCreate documentation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
fetch or axios) to get the data you want to insert.
2. Check if the data exists in Strapi by using a data hook like useList with appropriate filters.
3. If the data does not exist (empty array), create a new record in Strapi using the useCreate hook.
Here is a conceptual example:
Key points:
- You must handle the external API call yourself (Refine does not abstract this).
- The check for existence is done via useList and filters.
- The creation is done via useCreate if the list is empty.
There is no built-in "create if not exists" or "upsert" in Refine or the Strapi data provider, so this manual orchestration is required.See useCreate documentation ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
robust-apricotOP•13h ago
@kapa.ai can I use useCustom instead of fetch here?
Let me check the knowledge base for you again. One moment! :books:
----------------------
Yes, you can use Refine's
useCustom hook instead of a direct fetch call to make requests to an external API. The useCustom hook is designed for sending custom queries to any endpoint, not just your main data provider, and supports specifying the URL, HTTP method, headers, query parameters, and more. The response will be managed with React Query, giving you features like caching and loading states.
Here’s a basic example of how you might use useCustom to call an external API:
You can then use the data from this hook in your logic to check if it exists in Strapi and, if not, create a new record.
Summary:useCustom is a suitable and recommended alternative to fetch for custom API requests in Refine, as described in the documentation and examples provided here and here.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
robust-apricotOP•13h ago
@kapa.ai can i put useCustom inside the useEffect?
Let me check the knowledge base for you again. One moment! :books:
----------------------
You should not call the
Call
Do not put
See related issue and warning ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
useCustom hook (or any React hook) inside a useEffect. According to the Rules of Hooks, hooks must be called at the top level of your React function component, not inside loops, conditions, or nested functions like useEffect. This rule applies to all hooks, including useCustom.
If you call a hook inside useEffect, you will get a warning or error similar to:
Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.This is confirmed by a GitHub issue where such usage led to warnings in the console. Correct usage:
Call
useCustom at the top level of your component, and use useEffect for imperative logic if needed, but not for calling hooks themselves.
Summary:Do not put
useCustom inside useEffect. Always call hooks at the top level of your component, not inside other hooks or functions.See related issue and warning ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
robust-apricotOP•13h ago
@kapa.ai how can i make it call only in the useeffect and not on the component, or should I use fetch instead?
Let me check the knowledge base for you again. One moment! :books:
----------------------
You cannot use
This pattern allows you to control when the request is made, similar to how you would use
If you want full imperative control and do not need React Query's features, you can use
- Do not call
useCustom (or any React hook) only inside a useEffect—hooks must be called at the top level of your component, not conditionally or inside other functions like useEffect. This is a fundamental React rule and is confirmed in the knowledge sources, which show useCustom being used at the top level of the component, not inside useEffect or any other function block useCustom documentation.
If you need to trigger a request only in response to an event (such as a button click or inside an effect), you have two main options:
1. Use useCustom with queryOptions: { enabled: false } and call refetch manually:This pattern allows you to control when the request is made, similar to how you would use
fetch inside useEffect. You initialize the hook at the top level, but the request only fires when you call refetch (for example, inside a useEffect or event handler).
This approach is also recommended in community discussions and GitHub issues for cases where you want to trigger a request manually GitHub Issue #2407.
2. Use fetch or another data-fetching library directly inside useEffect:If you want full imperative control and do not need React Query's features, you can use
fetch or axios inside useEffect as shown in the knowledge sources Next.js data fetching blog.
Summary:- Do not call
useCustom inside useEffect.
- To trigger a request only in useEffect, use useCustom with enabled: false and call refetch inside your effect.
- Alternatively, use fetch directly in useEffect if you do not need React Query features.
This approach is supported and recommended in the official documentation and community discussions.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.
robust-apricotOP•8h ago
@kapa.ai when i call refetch, can I add an argument for useCustom tu use in the query?
Let me check the knowledge base for you again. One moment! :books:
----------------------
When you call
- You cannot pass arguments directly to
refetch from the useCustom hook, you cannot pass new arguments directly to refetch to change the query parameters. The useCustom hook's refetch function will use the parameters (such as url, method, and config) that were initially provided when the hook was created.
If you want to change the query parameters (for example, to use a different query or payload), you need to update the props passed to useCustom (such as changing the config.query or config.payload), which will cause the hook to re-run with the new parameters. This is the standard pattern in Refine and is shown in the documentation and examples:
When properties are changed, theExample: Summary:useCustomhook will trigger a new request.
useCustom documentation
- You cannot pass arguments directly to
refetch in useCustom.
- To change the query, update the hook's props (e.g., state for config.query), then call refetch() to trigger the request with the new parameters.
This behavior is consistent with the documentation and examples provided for useCustom in Refine.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------<@267689263246606336> Kapa.ai is still learning and improving, please let me know how I did by reacting below.