onResult does not fire on the first load of useLazyQuery
minako-ph opened this issue Β· comments
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
.
Hello @minako-ph, I could not reproduce this issue.
Can you please create a minimal repro either in a github repo or using codesandbox so the team can debug this issue?
@nickmessing
Thank you for looking into this. I'll prepare a minimal project and share it with you.
As an additional note, I found that downgrading to 4.0.0-beta.9 makes onResult work as expected on the first load, while upgrading to 4.0.0-beta.10 causes onResult to not fire only on the first load. I suspect the following change might be the cause:
Please let me know if you need any further information. Thank you for your cooperation in resolving this issue.
@minako-ph There's version 4.0.2, did you test on that?
I upgraded from 4.0.0-beta.1 to 4.0.2 and noticed that the onResult stopped firing on the first load completion when using useLazyQuery. As a workaround, I tried downgrading the version. I found that it works up to 4.0.0-beta.9, but stops working from 4.0.0-beta.10 onwards.
Here are the results of my testing:
-
Working
4.0.0-beta.1
4.0.0-beta.9 -
Not Working
4.0.0-beta.10
4.0.2
Thank you for investing the time into this. Unfortunately as you can see I couldn't reproduce it in codesandbox (and locally).
If you could please create a minimal repro either as a github project or in codesandbox - that will help us investigate the issue further.
Sorry for the inconvenience