AWS file upload query cache invalidation after creation
Using version 0.14.2 on MacOS
I have a query to get a team
And the team returns a logo (File) if there is one
I also have a form that uploads a file and uses an action to do it.
When I upload the file and connect it to the team, I expect the
getTeamById
query to invalidate the cache since I have the File entity in the query and the Team entity in the createFile
action. Right now when I upload a new photo, the query invalidates and errors out with a 404 from AWS because it can't find the file. If I do a full page refresh, it loads fine. Is there a way I could do a sleep or something to wait for it to finish uploading?5 Replies
Hi @wardbox. 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 information provided, it seems like you're experiencing a timing issue where the cache invalidation and refetching of the
getTeamById
query is happening before the file has finished uploading to AWS. This results in a 404 error because the file isn't available at the time of the query.
Wasp currently uses react-query
for query management and automatic Entity-based Query cache invalidation. This means that Wasp invalidates a Query's cache whenever an Action that uses the same Entity is executed. In your case, the createFile
action and getTeamById
query both use the File
and Team
entities, so executing createFile
causes the cached result of getTeamById
to become outdated and Wasp invalidates it. This triggers a refetch of the data from the server.
However, there's no built-in mechanism in Wasp to delay this refetch until the file has finished uploading. One possible workaround could be to use the mechanisms provided by react-query
for manual cache invalidation. This would allow you to control when the cache is invalidated and the query is refetched.
Another option could be to use optimistic updates. This allows you to optimistically set cache values after performing an Action. You can configure them using Wasp's useAction
hook. This is currently the only manual cache invalidation mechanism Wasp supports natively.
Please note that Wasp is planning to implement better support for direct invalidation/updates and turning off automatic invalidation when needed, as mentioned in this Github issue (https://github.com/wasp-lang/wasp/issues/63).
For more information, you can refer to the following resources:
- Wasp Docs: Cache Invalidation (https://wasp-lang.dev/docs/data-model/operations/actions#cache-invalidation)
- Wasp Docs: The useAction
Hook and Optimistic Updates (https://wasp-lang.dev/docs/data-model/operations/actions#the-useaction-hook-and-optimistic-updates)
- Github Issue: Query invalidation/updating (https://github.com/wasp-lang/wasp/issues/63)
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @wardbox, 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?@kapa.ai this is my onSubmit function, could i refactor it to move the
axios.put
at the action level instead of on the client?Let me check the knowledge base for you. One moment! :books:
----------------------
Yes, you can refactor your
onSubmit
function to move the axios.put
request to the action level. This would involve creating a new action in your Wasp code that handles the file upload process. Here's a general idea of how you could do it:
1. Define a new action in your main.wasp
file:
2. In your actions.js
file, define the uploadFile
function. This function should take the uploadUrl
, file
, and fileType
as arguments, and use axios.put
to upload the file:
3. In your client-side code, import the uploadFile
action from wasp/client/operations
and use it in your onSubmit
function:
This way, the file upload process is handled on the server side, and your client-side code only needs to call the uploadFile
action with the necessary arguments.
Please note that this is a general guide and you might need to adjust the code to fit your specific use case. Also, remember to handle errors and edge cases appropriately in your code.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @wardbox, 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?@kapa.ai I got it working with a different method. I ended up keeping the upload on the client side, setting a
refetchLogo
boolean at the team page level, passing it to both the form and the logo component, and manually refetching when the file is uploaded to S3.
Let me check the knowledge base for you. One moment! :books:
----------------------
That's a great solution! You've effectively created a mechanism to manually trigger a refetch of the logo data when a new file is uploaded. By using a
refetchLogo
boolean and a useEffect
hook, you're able to control when the getDownloadFileSignedURL
query is refetched.
Here's a brief explanation of your solution for those who might find it helpful:
1. You're using the useQuery
hook from react-query
to fetch the logo data. The enabled
option is set to the value of refetchLogo
. This means the query will only run when refetchLogo
is true
.
2. You're using a useEffect
hook to trigger a refetch of the logo data whenever refetchLogo
changes. If refetchLogo
is true
, the refetch
function returned by useQuery
is called, and refetchLogo
is set back to false
.
3. When a new file is successfully uploaded, you're setting refetchLogo
to true
. This triggers the useEffect
hook, which in turn triggers a refetch of the logo data.
This is a clever use of react-query
's features to manually control when data is refetched. Great job!
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
Sorry @wardbox, 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?