Vue-apollo: Cannot query on button click? (in v4 composition API)

Created on 17 Jan 2020  路  16Comments  路  Source: vuejs/vue-apollo

Thanks for the library and effort given.

Similar to #121, I need an example how to query after an event (such as button click) in v4 composition API?

Further info:
I'm using vue-apollo with Nuxt. (Not @nuxtjs/apollo, because it doesn't support vue-apollo v4 yet.)

I tried below methods:

setup(props, context) {
  const enabled = ref(false)
  const q1 = useQuery(someQuery); // This is OK.

  // When I add below line, browser hangs during page load and waits forever.
  const q2 = useQuery(someQuery, null, { enabled: enabled.value });

  // Click handler throws when executed on click event.
  // Cannot read property '$isServer' of null at useQuery (useQuery.js?a2fd:25)
  function onClick() {
    const q3 = useQuery(someQuery);
  }
}

Many thanks,

Most helpful comment

Hello @mtsmachado8 i've found a working solution.

const queryOptions = ref({
  // whatever options you need
  enabled: false
})

const {result} = useQuery(<query>, <variables>,queryOptions)

// Do with the result what you need

const onClick = () => {
  queryOptions.value.enabled = true
}

This works for me and queries only once, when the Button is clicked. For me, instead of only doing the enabled as a ref, using the whole options-obejct as a ref did the trick.After that, if you want to requery on every click, you can use the refetch-Option from the useQuery like

const {result, refetch} = useQuery(<query>, <variables>,queryOptions)

const onClick = () => {
  if (!queryOptions.value.enabled) {
    queryOptions.value.enabled = true
    return 
  }
  refetch()
}

I hope this helps!

All 16 comments

Hi,

i searched for it a lot too, but it is writtin in their documentation vue apollo v4e

```


```

just add the "refetch" to the useQuery line and call it from the button click event.

Best Regards

@lTimeless, thanks for the answer. Does the example query the server two times (one in setup and one in refetch) or only one time (in refetch)?

Thanks.

@ozum You could Disable the query and on button click enable it andthan refetch the query.
Or set the polling interval really high and then refetch it on button click.
Maybe there is another way, but i couldn't find anything else so far.

@lTimeless thanks for the answer.

Hello @ozum I'm experiencing the same issue.
Did you find any solution that works without sending the query twice? For me the enable-Approach did work, but I think it would be cleaner if you just have to enable the quer without explicitly refetching it. Maybe you have found somethin?

@aaronschweig currently I have to switch back to old API, because some of the libraries I use did not support composition API yet. Using old API, I could not find a solution other than enable approach.

Hello guys, any solution for it yet? same problem.
Cannot read property '$isServer' of null at useQuery

Hello @mtsmachado8 i've found a working solution.

const queryOptions = ref({
  // whatever options you need
  enabled: false
})

const {result} = useQuery(<query>, <variables>,queryOptions)

// Do with the result what you need

const onClick = () => {
  queryOptions.value.enabled = true
}

This works for me and queries only once, when the Button is clicked. For me, instead of only doing the enabled as a ref, using the whole options-obejct as a ref did the trick.After that, if you want to requery on every click, you can use the refetch-Option from the useQuery like

const {result, refetch} = useQuery(<query>, <variables>,queryOptions)

const onClick = () => {
  if (!queryOptions.value.enabled) {
    queryOptions.value.enabled = true
    return 
  }
  refetch()
}

I hope this helps!

Thankss @aaronschweig, it really helped!!!

This seems very inelegant. Executing a query on click (or whatever event) should work as expected imo.

Is there a solution for this if you arent even using an event to trigger query? I'm using quasar ssr and am getting Error in data(): "TypeError: Cannot read property '$isServer' of null" in build ssr but no such error in dev ssr.

There is nothing special triggering the query its just within the setup function.

Is there a way to prevent the initial query from executing with useQuery? My code is written as follows:

export default function useUserQuery() {
  const { refetch } = useQuery(UserQuery);

  return async function fetchUser(userId) {
    const { data } = await refetch({ userId });
    return data.user;
  };
}

This works as intended, but the initial query is being run (without variables and thus is throwing an error in the console, but all subsequent queries with fetchUser(userId) work perfectly fine). I've tried using the enabled option but it seems like when you set enabled.value = true the query gets automatically re-run (and the value stored in result), which wouldn't work in my situation since I want to capture the result of the query in a callback (in this case, const {data} = await refetch({ userId })).

Can you get this disable/enable demo to work with the latest alpha version?
https://github.com/vuejs/vue-apollo/issues/1082

Both useLazyQuery usage and the fact that refetch returns a Promise to the fetched data are missing from the docs :\

Also, seems like there's no clean way to perform a one-shot request or reuse the same one on-demand (without loading it first).

In Options API you could do this

const result = await this.$apollo.query({
  query: gql`...`,
  variables: { param: 'hello' },
})

You still can, via context.root

const result = await root.$apollo.query({
  query: gql`...`,
  variables: { param: 'hello' },
})

Using load from useLazyQuery will "unblock" the query, which will start immediately, but won't return the answer if awaited.
My use case is a "search" which hits the databases as part of a multi-step filtering of the results. The order of the filters is important, so I must call them synchronously and only on-demand.

I guess I could create a Promise which wraps the result ref and resolve when it emits, but it feels a bit hacky.
Will keep using previous syntax in the meantime, keep up the good work!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

wangxiangyao picture wangxiangyao  路  4Comments

agosto-chrisbartling picture agosto-chrisbartling  路  4Comments

dsbert picture dsbert  路  4Comments

chadwtaylor picture chadwtaylor  路  3Comments

alx13 picture alx13  路  4Comments