0

I have a little weird problem. I'm creating the front-end of a blockchain app with react and web3. Everything is perfect and it connects fine, but when I reload the page and call the getNfts() function, it is called before web3 has been loaded and assigned. But if I use the navigation menu to load that page, everything loads without any problem. I don't know how to fix it so as not to mess up the code too much.

On page load (App.js):

const accountData = JSON.parse(localStorage.getItem("account"));
if (accountData && Date.now() < accountData.expiration) {
    console.log(accountData.data);
    if(accountData.data.accountCreated == "true"){
        connectWallet().then(() => {
            getNfts();
        });;
        console.log("hola");
    }
}else {
    localStorage.removeItem("account");
}

Connect.js: export async function connectWallet() { if (window.ethereum.networkVersion === "97") { if(localStorage.getItem("account") === null){ try { await window.ethereum.request({ method: 'wallet_requestPermissions', params: [{ eth_accounts: {} }], }); } catch (error) { console.error(error); } } const web3Modal = new Web3Modal({ providerOptions: providersOptions, autoConnect: true, });

  const web3ModalInstance = await web3Modal.connect();

  const web3ModalProvider = new ethers.providers.Web3Provider(web3ModalInstance);

  web3 = new Web3(window.ethereum);

  const firstAccount = await web3.eth.getAccounts().then(data=>data[0]);
  account = firstAccount;

  const expiration = Date.now() + 3600000;
  const data = {accountCreated: 'true'};
  localStorage.setItem("account", JSON.stringify({ data: data, expiration: expiration }));

  isConnected = true;

  const connectButton = document.querySelector('.menu-button');
  connectButton.textContent = 'Logout';

} else {
  window.ethereum.request({
    method: 'wallet_switchEthereumChain',
    params: [{ chainId: '0x61' }], // 0x38 Mainnet Bsc
}).then(() => {
    // connecting to wallet
    console.log('Changing chain...');
}).catch((error) => {
    // error, need to change to bsc testnet
    alert("Change to bsc testnet");
});
}

}

I have this error in console:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'eth') at getNfts (App.js:669:1) at App.js:934:1

I also don't know if there is any way to better handle the connection with the user. This is the best way I have found to save the user's account for 1 hour, after that time (if it is not still active) it will log out and ask you to log in again.

I use this part of code I check if the user has already been logged in the last hour, if so, it will not ask for authentication and will connect automatically, if that hour has passed and the localStorage has been removed, it will ask you to sign in metamask again. But I see that the code I have made is a bit shabby.

if(localStorage.getItem("account") === null){
    try {
        await window.ethereum.request({
          method: 'wallet_requestPermissions',
          params: [{ eth_accounts: {} }],
        });
      } catch (error) {
        console.error(error);
      }
}

1 Answer 1

0

You can try calling that function in useEffect() and pass web3 as parameter to that useEffect() so when web3 is loaded it calls the function again

useEffect = () => {
const accountData = JSON.parse(localStorage.getItem("account"));
if (accountData && Date.now() < accountData.expiration) {
    console.log(accountData.data);
    if(accountData.data.accountCreated == "true"){
        connectWallet().then(() => {
            getNfts();
        });;
        console.log("hola");
    }
}else {
    localStorage.removeItem("account");
}
,[web3]}

Lemme know if you face any issue

1
  • I still have the same error
    – Shadow
    Apr 28, 2023 at 11:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.