wladknd
wladknd

Reputation: 21

How to use Apollo-client hook useQuery inside another function?

I am trying to make a module for web3 authentication. For that I have a function which gets user's public address and makes a GraphqQL query to the back-end to see if it's present in the database.

export const useWeb3 = async () => {
    const [ user, setUser ] = useState({})

    if (!(window as any).ethereum) {
        window.alert('Please install MetaMask first.');
        return;
    }

    let web3: Web3 | undefined = undefined

    if (!web3) {
        try {
            // Request account access if needed
            await (window as any).ethereum.enable();

            // We don't know window.web3 version, so we use our own instance of Web3
            // with the injected provider given by MetaMask
            web3 = new Web3((window as any).ethereum);
        } catch (error) {
            window.alert('You need to allow MetaMask.');
            return [user];
        }
    }

    const coinbase = await web3.eth.getCoinbase()
    if (!coinbase) {
        window.alert('Please activate MetaMask first.')
        return [user]
    }
    console.log("COINBASE", coinbase)

    const publicAddress = coinbase.toLowerCase();
    // setLoading(true);

    const { data } = useQuery(QUERY_USER_BY_PUBLIC_ADDRESS, {
        variables: { publicAddress }
    })
    if(data) setUser(data)
    
    return [user]
    
}

So I have a custom hook useWeb3(). I made it a hook so I could call useQuery inside it. I import useWeb3 inside the other component and when I try to use it like that:

const [user] = useWeb3()

It says Type 'Promise<{}[] | undefined>' is not an array type.ts(2461) Welcome.component.tsx(34, 11): Did you forget to use 'await'?

The question is how can I implement the logic of taking public address and query back end with that inside a separate function so I could use it in other components?

Upvotes: 0

Views: 2286

Answers (1)

hwillson
hwillson

Reputation: 1399

If you just want to return the QUERY_USER_BY_PUBLIC_ADDRESS response data and aren't looking to have the results rendered as part of a React component, then you don't need to use the useQuery React hook here. Just use Apollo Client's query function directly, which returns a Promise:

...
// `client` here is your instantiated `ApolloClient` instance
const result = await client.query({ 
  query: QUERY_USER_BY_PUBLIC_ADDRESS, 
  variables: { publicAddress }
});
...

Upvotes: 1

Related Questions