Wait for useLazyQuery response

I need to call a query when submit button is pressed and then handle the response.

I need something like this:

const [checkEmail] = useLazyQuery(CHECK_EMAIL)
const handleSubmit = async () => {
  const res = await checkEmail({ variables: { email: values.email }})
  console.log(res) // handle response
}

Try #1:

const [checkEmail, { data }] = useLazyQuery(CHECK_EMAIL)
const handleSubmit = async () => {
  const res = await checkEmail({ variables: { email: values.email }})
  console.log(data) // undefined the first time
}

Thanks in advance!

Upvotes: 16

Views: 23097

Answers (5)

Thobias Nordgaard
Thobias Nordgaard

Reputation: 295

Simply do the following:

import { useLazyQuery } from '@apollo/client';

const [myQuery] = useLazyQuery(MY_GQL_QUERY)

const result = await myQuery({ variables: { some: 'variable' }})
console.log(result.data)

Upvotes: 2

dpatra
dpatra

Reputation: 62

In case someone wants to fetch multiple apis at single load, it could be achieved like this.

  • On Demand Load > e.g. onClick, onChange
  • On Startup > e.g. useEffect
import { useLazyQuery } from "@apollo/client";
import { useState, useEffect } from "react";
import { GET_DOGS } from "../../utils/apiUtils";
    
const DisplayDogsLazy = () => {
  const [getDogs] = useLazyQuery(GET_DOGS);
  const [data, setData] = useState([]);
    
    useEffect(() => {
     getAllData();
    }, []);

    const getAllData = async () => {
        const response = await getDogs();
        console.log("Awaited response >", response);
    };
    
      const handleGetDogsClick = async () => {
        const response = await getDogs();
        setData(response.data.dogs);
      };
    
      return (
        <>
          <button onClick={handleGetDogsClick}>Get Dogs</button>
    
          {data?.length > 0 && (
            <ul>
              {data?.map((dog) => (
                <li key={dog.id} value={dog.breed}>
                  {dog.breed}
                </li>
              ))}
            </ul>
          )}
        </>
      );
    };
    
export default DisplayDogsLazy;

Upvotes: 0

apacheco37
apacheco37

Reputation: 99

You could also use the onCompleted option of the useLazyQuery hook like this:

const [checkEmail] = useLazyQuery(CHECK_EMAIL, {
  onCompleted: (data) => {
    console.log(data);
  }
});

const handleSubmit = () => {
  checkEmail({ variables: { email: values.email }});
}

Upvotes: 8

kurtko
kurtko

Reputation: 2126

This works for me:

const { refetch } = useQuery(CHECK_EMAIL, {
  skip: !values.email
})

const handleSubmit = async () => {
  const res = await refetch({ variables: { email: values.email }})
  console.log(res)
}

Upvotes: 19

After all, this is my solution.

export function useLazyQuery<TData = any, TVariables = OperationVariables>(query: DocumentNode) {
  const client = useApolloClient()
  return React.useCallback(
    (variables: TVariables) =>
      client.query<TData, TVariables>({
        query: query,
        variables: variables,
      }),
    [client]
  )
}

Upvotes: 10

Related Questions