When I make the call contract?.methods.name().call() within the same scope as loading providers, everything works perfectly fine. It also works fine when I do a page reload.
However, if I make the call contract?.methods.name().call() in another useEffect, I encounter an error stating 'Cannot read properties of undefined (reading 'methods')' when I do a page reload. It appears that this function is being called before the contract is fully loaded or available on the server side, especially since I am using Next.js
Is there a way for me to resolve this issue and still be able to make the call contract?.methods.name().call() in another useEffect and during a page reload? Is that even feasible? Below is the code snippet. Thank you
const Demo = (props: Props) => {
const [web3Api, setWeb3Api] = useState<{
web3: Web3 | undefined;
isProviderLoaded: boolean;
provider: any;
contract: any;
name: string;
}>({
isProviderLoaded: false,
web3: undefined,
provider: undefined,
contract: undefined,
name: "",
});
const [contractName, setContractName] = useState<string>("");
const loadProvider = async () => {
const provider = await detectEthereumProvider();
const web3 = new Web3(provider as any);
if (provider) {
const contract = await loadContract("Demo", web3);
const name = await contract?.methods.name().call();
setWeb3Api({
web3,
provider,
contract,
isProviderLoaded: true,
name,
});
}
};
useEffect(() => {
const getContractName = async () => {
// todo Cannot read properties of undefined (reading 'methods')
const contractName = await web3Api.contract.methods.name().call();
setContractName(contractName);
};
getContractName();
}, [web3Api]);
useEffect(() => {
loadProvider();
}, []);
return (
<Layout>
<p>Demo</p>
{/* Work OK */}
<p>{web3Api.name}</p>
{/* Not OK */}
<p>{contractName}</p>
</Layout>
);
};
export default Demo;