获取查询后有条件地执行 graphql 突变

Conditionally execute a graphql mutation after a query is fetched

场景

当用户通过身份验证时(isAuthenticated booelan ref):

  1. 通过对后端的 graphql 调用检查用户是否有偏好 (useViewerQuery)
  2. 如果用户没有首选项,请设置默认值 (useSetPreferenceDefaultMutation)

问题

查询和变异在 graphql 游乐场和 Vue 应用程序中都能正常工作。它们是在后台使用 graphql codegenerator which uses useQuery and useMutation 生成的。

我们遇到的问题是我们无法定义正确的顺序。有时 useSetPreferenceDefaultMutationuseViewerQuery 之前执行。这会将用户的设置重置为默认值,这不是所需的行为。

此外,在页面刷新时一切正常。但是,当关闭重新打开页面时,它总是调用 useSetPreferenceDefaultMutation.

代码

export default defineComponent({
  setup() {
    const {
      result: queryResult,
      loading: queryLoading,
      error: queryError,
    } = useViewerQuery(() => ({
      enabled: isAuthenticated.value,
    }))

    const {
      mutate: setDefaultPreferences,
      loading: mutationLoading,
      error: mutationError,
      called: mutationCalled,
    } = useSetPreferenceDefaultMutation({
      variables: {
        language: 'en-us',
        darkMode: false,
      },
    })

    onMounted(() => {
      watchEffect(() => {
        if (
          isAuthenticated.value &&
          !queryLoading.value &&
          !queryResult.value?.viewer?.preference &&
          !mutationCalled.value
        ) {
          void setDefaultPreferences()
        }
      })
    })

    return {
      isAuthenticated,
      loading: queryLoading || mutationLoading,
      error: queryError || mutationError,
    }
  },
})

失败的努力

感谢@xadm 的评论,现在通过在查询中使用 onResult event hook 修复了问题,因此它将在之后执行突变。

onResult(handler): Event hook called when a new result is available.

export default defineComponent({
  setup(_, { root }) {
    const {
      loading: queryLoading,
      error: queryError,
      onResult: onQueryResult,
    } = useViewerQuery(() => ({
      enabled: isAuthenticated.value,
    }))

    const {
      mutate: setDefaultPreferences,
      loading: mutationLoading,
      error: mutationError,
    } = useSetPreferenceDefaultMutation({
      variables: {
        language: 'en-us',
        darkMode: false,
      },
    })

    onQueryResult((result) => {
      if (!result.data.viewer.preference) {
        void setDefaultPreferences()
      }
    })

    return {
      isAuthenticated,
      loading: queryLoading || mutationLoading,
      error: queryError || mutationError,
    }
  },
})