Search code examples
javascriptethereumsolidityweb3jsmetamask

getAccount() in web3 produce two different errors on two different browsers


I am trying to follow a tutorial and keep getting two different errors:

on chrome:

"Unhandled Rejection (TypeError): Cannot read property 'then' of undefined"

on Firefox:

Unhandled Rejection (TypeError): web3.eth.getAccounts(...) is undefined

my code is simple, it's a react project with localhost provider using Ganache and npm:

 async loadBlockchainData(){
  const web3 = await window.web3
  const acc = await web3.eth.getAccounts().then(console.log);      
  this.setState({account: acc[0]})

Why does getAccounts returning undefined in the first place? and why chrome is producing this error while firefox is not?

my metamask is logged in in both browsers (and accepted the conntection)

web3 version is [email protected]

EDIT: here is how I initialized web3:

 async componentWillMount(){
 await this.loadWeb3();
 await this.loadBlockchainData();
    }    
  async loadWeb3() {

   window.addEventListener('load', async () => {
     if (window.ethereum) {
       window.web3 = new Web3(window.ethereum);
       await window.ethereum.enable();

     } 

     else if (window.web3) {
      window.web3 = new Web3(window.web3.currentProvider);

     }

     else {
      console.log('Non-Ethereum browser detected. You should consider trying MetaMask!');
     }
   });

}

Solution

  • Most probable cause is that you are not initializing web3 correctly. If you are using metamask then initialize web3 like so:

    const web3 = new Web3(window.web3.currentProvider);
    

    And at the start of file import Web3.

    import Web3 from 'web3';
    

    Also be extra careful about not to mix upper case Web3 with lower case web3.

    Edit after question edit and comment

    I don't know which tutorial you are following. But you don't have to await on window.web3 in loadBlockchainData() and you dont have to listen on window load in loadWeb3().

    Simplified loadWeb3()

    async loadWeb3() {
        if (window.ethereum) {
            window.web3 = new Web3(window.ethereum);
            await window.ethereum.enable();
        } else if (window.web3) {
            window.web3 = new Web3(window.web3.currentProvider);
        } else {
            console.log("Non-Ethereum browser detected. You should consider trying MetaMask!");
        }
    }
    

    and loadBlockchainData()

    async loadBlockchainData() {
        const web3 = window.web3;
        const acc = await web3.eth.getAccounts();
        this.setState({ account: acc[0] });
    }
    

    web3 version 1.2.1 and react version 16.10.2