Description
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:
- Define a
useLazyQuery
as follows:
const {
result: myResult,
load: myLoad,
onResult: onMyResult,
} = useLazyQuery<MyQuery>(
MyQueryDocument,
myQueryVariables,
{
clientId: 'myClient',
fetchPolicy: 'no-cache',
}
)
- Set up an
onResult
callback:
onMyResult(() => {
console.log(`📣: onMyResult triggered`)
isFetched.value = true
})
- Trigger the
load
function based on a condition:
watch(
myCondition,
newCondition => {
console.log(`📣: myCondition changed`, `newCondition: ${newCondition}`)
if (newCondition) {
myLoad()
}
},
{ immediate: true }
)
- 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
.