Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apollo Hooks - useLazyQuery not using onCompleted option if passed on query

I have a custom debounce hook for apollo lazy queries:

import {useLazyQuery} from '@apollo/react-hooks';
import debounce from "lodash/debounce";

export function useDebouncedQuery(schema) {
    const [doQuery, {...rest}] = useLazyQuery(schema);

    const query = React.useCallback(debounce(doQuery, 1000), []);

    return [query, {
        ...rest
    }]
}

This works, other than the onCompleted option. When implementing the hook like this:

const [doQuery] = useDebouncedQuery(query);
doQuery({
    onCompleted: data => {
        console.log(data);
    }
})

...the onCompleted option doesn't fire. But, if I change the hook to be:

export function useAsyncSelectQuery(schema, options) {
    const [doQuery, {...rest}] = _useLazyQuery(schema, options);
    ...

.. and implement it like this, it works:

const [doQuery] = useDebouncedQuery(query, {
    onCompleted: data => {
        console.log(data);
    }
});

Why is this? Am I doing something wrong? I have separate logic that needs to handle the data passed to onCompleted in different places so I can't pass that option when the query gets initialized. Any help is greatly appreciated.

like image 888
jrkt Avatar asked Aug 09 '19 16:08

jrkt


2 Answers

So, the function returned by the useLazyQuery hook doesn't have an onCompleted property on the options parameter, so you can't use it.

According to the docs: https://www.apollographql.com/docs/react/api/react-hooks/#result-1, the function returns a QueryLazyOptions, these are the params:

export interface QueryLazyOptions<TVariables> {
    variables?: TVariables;
    context?: Context;
}

I think a good solution to the task you're trying to achieve is to use an useEffect hook, to watch for changes in the property data returned by the useDebouncedQuery hook and then handle the data as you want to.

Code below:

const [doQuery, { data, loading, error }] = useDebouncedQuery(
  QUERY
);

useEffect(() => {
  if (data && data.property && !loading) {
    // handle data here
  }
}, [data, loading]);

function handleQuery() {
  doQuery();
}

Hope this help!

like image 112
Pedro Gomes Avatar answered Sep 19 '22 12:09

Pedro Gomes


You can't set onCompleted when you're calling useLazyQuery, but you can when you're defining useLazyQuery.

So this will not work:

const [doQuery] = useDebouncedQuery(query);
doQuery({
    onCompleted: data => {
        console.log(data);
    }
})

But this will work:

const [doQuery] = useDebouncedQuery(query, {
    onCompleted: data => {
        console.log(data);
    }
});
doQuery()
like image 20
Ryan Jones Avatar answered Sep 19 '22 12:09

Ryan Jones