Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

usequery() result set to undefined while refetching after updating variable #1483

Open
andgith opened this issue Jun 15, 2023 · 2 comments
Open

Comments

@andgith
Copy link

andgith commented Jun 15, 2023

Describe the bug
The value of result is undefined while a refetch occurs after a variable update.

const variables = ref({
  id: props.id,
  sort: sort.value,
  group: group.value,
});

const { result, error } = useQuery(searchQuery, () => variables);

Expected behavior
In versions before beta-2 did not set result to undefined during a refetch.

Versions
vue: 3.3.4
vue-apollo: ^4.0.0-beta.1
@apollo/client: 3.7.15

@andgith andgith changed the title usequery result set to undefined while refetching after updating variable usequery() result set to undefined while refetching after updating variable Jun 15, 2023
@Csszabi98
Copy link
Contributor

Seems like the culprit is this line: https://github.com/vuejs/apollo/blob/v4/packages/vue-apollo-composable/src/useQuery.ts#L325

This method gets called twice when variables change due to the query being restarted. For the first call, "data" is not present as the query is still loading so variables get cleared. For the send call, "data" will be set (for a successful request that is) and the "result" will have a value again.

Proposed solution:

function processNextResult (queryResult: ApolloQueryResult<TResult>) {
    result.value = queryResult.data && Object.keys(queryResult.data).length === 0 ? result.value : queryResult.data
    // Old: result.value = queryResult.data && Object.keys(queryResult.data).length === 0 ? undefined : queryResult.data
    loading.value = queryResult.loading
    networkStatus.value = queryResult.networkStatus
    // Wait for handlers to be registered
    nextTick(() => {
      resultEvent.trigger(queryResult)
    })
  }

@Csszabi98
Copy link
Contributor

A simple workaround:

const useStableQueryResult = <TResult, TVariables extends OperationVariables>({
  result,
}: Pick<UseQueryReturn<TResult, TVariables>, 'result'>) => {
  const stableResult = ref(result.value);

  watch(result, (newResult) => {
    if (newResult) {
      stableResult.value = newResult as UnwrapRef<TResult>;
    }
  });

  return stableResult;
};

You can also make this the default behavior of useQuery via a wrapper, or just use it directly with your query.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants