Reputation: 918
I am trying to use a smart contract just after I instantiate it. However, I get an error:
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'call')
I thought I did not have access to the functions just after instantiating it, but it does not seem to be it. What else could it be? Someone already had a similar problem?
Current code:
import React, { useEffect, useState } from 'react';
import Head from 'next/head';
import { useWeb3React } from '@web3-react/core';
import NFTCollectionArtifact from 'artifacts/contracts/NFTCollection.sol/NFTCollection.json';
import { Contract, ethers, Signer } from 'ethers';
import { Provider } from '@openmint/utils/provider';
export const Index = () => {
const context = useWeb3React<Provider>();
const { library } = context;
const [contractInstance, setContractInstance] = useState<Contract | undefined>();
const [signer, setSigner] = useState<Signer>();
const [name, setName] = useState<String>('');
useEffect(() => {
const address = '0x5FbDB2315678afecb367f032d93F642f64180aa3';
const nftCollection = new ethers.Contract(
address,
NFTCollectionArtifact.abi,
signer
);
setContractInstance(nftCollection);
}, []);
useEffect(() => {
if(!contractInstance) return;
const setContractName = async () => {
try{
console.log(await contractInstance?.name());
setName(await contractInstance?.name());
} catch(e){
console.error('my error', e);
}
}
setContractName();
}, [contractInstance]);
useEffect((): void => {
if (!library) {
setSigner(undefined);
return;
}
setSigner(library.getSigner());
}, [library]);
return (
<>
<Head>
<title>Preview NFTs</title>
</Head>
</>
);
};
export default Index;
Upvotes: 0
Views: 4629
Reputation: 357
Just in case - this can happen if you simply don't provide a third parameter when creating a contract object:
contract = new ethers.Contract(address, abi);
The proper way would be:
contract = new ethers.Contract(address, abi, providerOrSigner);
I wish there was a clearer error message that literally said you did not supply a signer/provider
. Instead of silently accepting this on contract object creation, and then later throwing the cryptic TypeError: Cannot read properties of null (reading 'call')
with a meaningless stack trace.
Upvotes: 1
Reputation: 151
This is usually seen if the signer object is invalid/undefined. Any activity with an invalid signer object like contract creation, call, send transaction, etc, will have the error: TypeError: Cannot read properties of null (reading 'call') at Contract. (node_modules@ethersproject\contracts\src.ts\index.ts:397:47)...
Upvotes: 1
Reputation: 918
Ok, I still do not understand the whole picture of why the following solution works, but if anyone out there is having a similar issue, this was what worked for me:
useEffect((): void => {
if (!contractInstance) {
return;
}
async function getStatus(MyContract: Contract): Promise<void> {
const name = await MyContract.name();
const newStatus: StatusInterface = {
...status,
name
};
console.log('newStatus', newStatus);
if (!isEqual(status, newStatus)) {
setStatus(newStatus);
}
}
getStatus(contractInstance);
}, [contractInstance, status, account]);
My understanding is that this was a scope issue.
Upvotes: 2
Reputation: 850
Make sure your environment config has an account set up correctly. In my case this was happening because I had an extra WALLET_PRIVATE_KEY=
line set in my .env when using ethers + hardhat.
Upvotes: 1