Skip to content

onResult does not fire on the first load of useLazyQuery #1543

Open
@minako-ph

Description

@minako-ph

Describe the bug

When using useLazyQuery, the onResult callback does not fire on the first execution of the load function, even though the result is updated correctly.

To Reproduce

Steps to reproduce the behavior:

  1. Define a useLazyQuery as follows:
const {
  result: myResult,
  load: myLoad,
  onResult: onMyResult,
} = useLazyQuery<MyQuery>(
  MyQueryDocument,
  myQueryVariables,
  {
    clientId: 'myClient',
    fetchPolicy: 'no-cache',
  }
)
  1. Set up an onResult callback:
onMyResult(() => {
  console.log(`📣: onMyResult triggered`)
  isFetched.value = true
})
  1. Trigger the load function based on a condition:
watch(
  myCondition,
  newCondition => {
    console.log(`📣: myCondition changed`, `newCondition: ${newCondition}`)
    if (newCondition) {
      myLoad()
    }
  },
  { immediate: true }
)
  1. Observe the logs:
📣: myResult undefined
📣: myCondition changed newCondition: true
📣: myResult {data: {…}}data: {items: Array(10), totalCount: 10, __typename: 'MyDataType'}[[Prototype]]: Object
📣: myCondition changed newCondition: false
📣: myCondition changed newCondition: true
📣: myResult {data: {…}}
📣: onMyResult triggered

Expected behavior

The onResult callback should be triggered whenever the result is updated, including on the first execution of the load function.

Versions

  • "vue-server-renderer": "2.7.14"
  • "@vue/compat": "3.3.4",
  • "@vue/apollo-composable": "^4.0.2"
  • "@apollo/client": "^3.7.15"

Additional context

The issue seems to be caused by a mismatch in the handling of asynchronous operations between useLazyQuery and useQuery.

In useLazyQuery, the first load returns a Promise that resolves when the query result is received. However, the resolution of this Promise does not directly trigger the onResult callback defined in useQuery.

In useQuery, the onResult callback is triggered by a watch on the result ref. However, this watch does not react immediately to the changes made to result inside the Promise returned by useLazyQuery's load function.

As a result, although myResult is updated after the first load, onMyResult is not triggered until the next load call.

To resolve this issue, we might need to find a way to synchronize the state between useLazyQuery and useQuery, possibly by explicitly triggering the watch in useQuery after result is updated in useLazyQuery, or by making the watch in useQuery aware of the Promise returned by useLazyQuery.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions