hook is not being called in handleSubmit

Viewed 153

I have a hook that I want to call in handleSubmit. The data from this hook will be passed to another hook, and based on the response from the second hook, I want to push different pages.

The first hook:

const write = useContractWrite(
      {
        addressOrName: Address,
        contractInterface: Interface,
      },
      'entry',
      { 
        args: [firstAnswer.trim().toLowerCase(), secondAnswer.trim().toLowerCase()],
        overrides: { 
          value: ethers.utils.parseEther("0.01") 
       }
      }
    )

Documentation for useContractWrite

I have another hook that relies on the data of the useContractWrite hook:

const waitForTransaction = useWaitForTransaction({
      wait: write!.data?.wait,
      onSettled(data, error) {
        console.log("Settled", { data })
      }
    });

Docs for useWaitForTransaction

And finally, my handleSubmit:

async function handleSubmit() {
      if (firstAnswer.length == 0 || secondAnswer.length == 0) {
        setInputError(true);
      }
      else {
        setInputError(false);

        //write
        const txn = write;
        // console.log(write + "writeData")

        //wait            
        // console.log(waitForTransaction.data + "waitData")
      }
    }
  • Unfortunately, the write function is not being called in handleSubmit. So, I make it callable

  • Changing the write to the following: const { write } = useContractWrite makes it callable const txn = write();

  • But, I am unable to pass the txn!.data.wait to useWaitForTransaction like so:

     const txn = write();
    
     //wait
     waitForTransaction({wait: txn!.data?.wait});```
    
    
  • The error I get when attempting to pass txn.data.wait to waitForTransaction is that the waitForTransaction is not callable This expression is not callable.

  • So, I make it callable: const { waitForTransaction } = useWaitForTransaction({...})

  • Now, I get the following error on the useWaitForTransaction Hook: Property 'waitForTransaction' does not exist on type 'Pick<QueryObserverResult<TransactionReceipt, Error>, "data" | "error" | "isError" | "isLoading" | "isSuccess" | "isFetched" | "isFetching" | "isRefetching" | "refetch" | "fetchStatus"> & { ...; }'

I am sure there is an easy fix to this, but I do not see where the issue lies. I have followed the docs to a tee and it is not working.

1 Answers

According to the docs, the waitForTransaction is the whole return value, not a property of the returned value, so you need to drop the curly braces.

const waitForTransaction = useWaitForTransaction({...})

Another problem you will have is that hooks cannot be called conditionally, so doing this is illegal in hook-land

else {
  ...
  // cannot do this inside if () {} else {}
  const waitForTransaction = useWaitForTransaction({...})
}

Looking at the wagmi example, I would add the handleSubmit like this

import { useContractWrite, useWaitForTransaction } from 'wagmi'

function App() {

  const [inputError, setInputError] = useState(false)

  const contractWrite = useContractWrite(
    {
      addressOrName: '0xecb504d39723b0be0e3a9aa33d646642d1051ee1',
      contractInterface: wagmigotchiABI,
    },
    'feed',
  )

  const handleSubmit = () => {
    const hasError = firstAnswer.length == 0 || secondAnswer.length == 0;
    setInputError(hasError)
    if (!hasError) {
      contractWrite.write()       // call write method of contract
    }
  }

  // use with conditional inside hook call
  const waitForTransaction = useWaitForTransaction({
    wait: contractWrite.data?.wait 
  })
}
Related