vuejs / apollo

🚀 Apollo/GraphQL integration for VueJS
http://apollo.vuejs.org
MIT License
6.02k stars 522 forks source link

subscribeToMore is called twice when a reactive variable is changed #1560

Open robin-wallberg opened 3 months ago

robin-wallberg commented 3 months ago

Describe the bug It seems that subscribeToMore is called twice when a query and a subscription both depend on a reactive variable.

To Reproduce Example:

const a = ref(1)

const { subscribeToMore } = useQuery(
  someQuery,
  () => ({
    a: a.value,    
  })
)

subscribeToMore(() => ({
  document: someSubscription,
  variables: {
    a: a.value,
  }
}))

In the example above, if we set a.value = 2 and inspect websocket traffic or debug the code we notice that subscribeToMore is called twice, setting up two subscriptions with variables a: 2. One of the new subscriptions is then then immediately closed/completed.

If we instead passed a plain object to subscribeToMore like this:

subscribeToMore({
  document: someSubscription,
  variables: {
    a: a.value,
  }
})

subscribeToMore would only be invoked once but with the old value 1, we want the subscription to be started with the new value 2, same as the query.

Our guess is that this happens because when a.value is changed:

  1. useQuery stops & starts and triggers subscribeToMore
  2. The reactive function passed to subscribeToMore triggers a watch which in turn triggers subscribeToMore

Expected behavior subscribeToMore to be called once with variable a: 2 after variable a was changed to 2.

Versions vue: 3.4.21 @vue/apollo-composable: 4.0.2 @vue/apollo-option: 4.0.0 @apollo/client: 3.7.1

dominikklein commented 3 months ago

I had yesterday the same finding, was first thinking it's something in our code, but seems to be not :-)