Reputation: 2715
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.
Upvotes: 10
Views: 12453
Reputation: 31
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()
Note:
Execute function (first tuple item): Function that can be triggered to execute the suspended query. After being called, useLazyQuery behaves just like useQuery. The useLazyQuery function returns a promise that fulfills with a query result when the query succeeds or fails.
So when you call the excute function doQuery
it'll behave like doing the thing and if it success, it'll go and call the onCompleted
function declared in the useLazyQuery
.
Upvotes: 3
Reputation: 143
Pass the onCompleted
function when you init the useLazyQuery
const [doQuery] = useDebouncedQuery(query, {
onCompleted: data => {
console.log(data);
}
});
doQuery()
Upvotes: -3
Reputation: 106
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!
Upvotes: 7