useUpdateCharacter.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // noinspection JSIgnoredPromiseFromCall
  2. export const useUpdateCharacter = defineMutation(() => {
  3. const queryCache = useQueryCache()
  4. const { mutate, ...mutation } = useMutation({
  5. onMutate({ id, updates }) {
  6. // save the current character and character list
  7. const oldCharacterList = queryCache.getQueryData(characterListQuery.key)
  8. // find the index of the mutated character
  9. const characterIndex = _findIndex(oldCharacterList, { id })
  10. let oldOptions, oldCharacter, newCharacter, newCharacterList
  11. if (characterIndex >= 0) {
  12. // save the options and character
  13. oldOptions = queryCache.getQueryData(characterOptionsQuery.key)
  14. oldCharacter = oldCharacterList[characterIndex]
  15. // create the new character
  16. newCharacter = { ...oldCharacter, ...updates }
  17. // create a copy of the character list with the updated character
  18. newCharacterList = oldCharacterList.toSpliced(characterIndex, 1, newCharacter)
  19. // calculate new character options
  20. const newOptions = getCharacterOptions(newCharacterList)
  21. // update caches
  22. queryCache.setQueryData(characterListQuery.key, newCharacterList)
  23. queryCache.setQueryData(characterOptionsQuery.key, newOptions)
  24. queryCache.remove({ key: characterByIdQuery(id).key })
  25. // cancel (without refreshing) queries depending on the character
  26. queryCache.cancelQueries({ key: characterListQuery.key })
  27. queryCache.cancelQueries({ key: characterByIdQuery(id).key })
  28. }
  29. // pass the id, old and new character, and character lists to the other hooks
  30. return { id, oldCharacter, newCharacter, oldCharacterList, newCharacterList, oldOptions }
  31. },
  32. mutation: ({ id, updates }) => useEmit("character:update", id, updates),
  33. onSettled(_data, _error, _vars, { id, newCharacter }) {
  34. // invalidate the queries to refetch the new data
  35. if (newCharacter) {
  36. queryCache.invalidateQueries({ key: characterListQuery.key })
  37. queryCache.invalidateQueries({ key: characterByIdQuery(id).key })
  38. }
  39. },
  40. onError(err, _vars, { id, oldCharacter, oldCharacterList, oldOptions, newCharacterList }) {
  41. // before applying the rollback, check if the values in the cache are the same
  42. // in case the cache was updated by another mutation or query
  43. if (newCharacterList === queryCache.getQueryData(characterListQuery.key)) {
  44. queryCache.setQueryData(characterListQuery.key, oldCharacterList)
  45. queryCache.setQueryData(characterOptionsQuery.key, oldOptions)
  46. queryCache.setQueryData(characterByIdQuery(id).key, oldCharacter)
  47. }
  48. // handle the error
  49. console.error("[useUpdateCharacter] [onError]", err)
  50. },
  51. onSuccess() {}
  52. })
  53. return {
  54. ...mutation,
  55. updateCharacter: (id, updates) => mutate({ id, updates })
  56. }
  57. })