samdenty / gqless

a GraphQL client without queries
https://gqless.com
3.66k stars 54 forks source link

[BUG] If i dont read any prop of mutation result, mutation not calls #186

Open MaxmaxmaximusAWS opened 3 years ago

MaxmaxmaximusAWS commented 3 years ago

this not call mutation

  const [sendMessage] = useMutation((mutation) => {
    return mutation.createMessage({ text: 'lol' })
  })

  <button onClick={()=> sendMessage()}>Send</button>

this call mutation

  const [sendMessage] = useMutation((mutation) => {
    const message = mutation.createMessage({ text: 'lol' })
    return message.id
  })

  <button onClick={()=> sendMessage()}>Send</button>

Solution:

if user not fire "get" caps of Proxy in mutation handler, you must assume that the value returned by the mutation is irrelevant to the user, but the mutation must be performed. What "mutation query" to generate based on this? Hmm, well, you have the whole scheme, find something related to the type ID, or, in extreme cases, the banal request "__typename"

P.S. By the way, if I do PR for the Issue place, is that welcome?

PabloSzx commented 3 years ago

P.S. By the way, if I do PR for the Issue place, is that welcome?

for sure it is 👍

Varal7 commented 3 years ago

Is there any workaround for this? When the return type is an object, doing as shown above but if the return type is null, then it's just not possible?

PabloSzx commented 3 years ago

Is there any workaround for this? When the return type is an object, doing as shown above but if the return type is null, then it's just not possible?

if the return type is nullable you can simply do "mutationFoo?.__typename", and if the mutations return scalars this issue doesn't apply

hpohlmeyer commented 3 years ago

FYI: If you need to work around this but want to return the full result of the mutation you need to make sure to access at least one property, even if you do not need it.

const [sendMessage] = useMutation((mutation) => {
  const message = mutation.createMessage({ text: 'lol' })
  if (message.__typename) {}
  return message;
})

<button onClick={()=> sendMessage()}>Send</button>

This issue also messes with refetchQueries. They run, but their order is reversed, so the refetch query runs before the actual mutation. The missing property access was culprit.