Enable web3 issue

Hi, I’m new to react and moralis, I want to display user balance after authenticate, so I code my function inside useEffect hook like this:

import { useMoralis } from "react-moralis";
import { useEffect, useState } from "react";
function App() {
  const { authenticate, isAuthenticated, user, logout, Moralis } = useMoralis();
  const { enableWeb3, isWeb3Enabled, web3 } = useMoralis();
  const [balance, setBalance] = useState("loading");

  function getBalance() {
    if (isWeb3Enabled)
      web3.eth
        .getBalance(user.get("ethAddress"))
        .then((res) => setBalance(res));
    console.log("web3 is enabled :", isWeb3Enabled);
  }

  useEffect(() => {
    if (isAuthenticated) {
      enableWeb3();
      getBalance();
    }
  }, [isAuthenticated]);

  return (
    <div className="App">
      <button onClick={() => authenticate()}>login</button>
      <button onClick={() => console.log("web3 is enabled: ", isWeb3Enabled)}>
        web3State
      </button>
      {isAuthenticated && <button onClick={() => logout()}>logout</button>}
      {isAuthenticated && <p>user id:{user.id}</p>}
      <p>account balance:{balance}</p>
    </div>
  );
}

export default App;


So this should enable web3 and get balance after authenticate, however, the console log the isweb3enabled is false and won’t execute the web3.eth.getbalance function, which confuses me, at first I thought it might be the reason that isweb3enabled value will take few milliseconds to change after enableweb3() is executed, so I delayed the getBalance function for 2 seconds after enableweb3(), and added a button to manually get isweb3enabled value like this.

useEffect(() => {
    if (isAuthenticated) {
      enableWeb3();
      setTimeout(() => {
        getBalance();
      }, 2000);
    }
  }, [isAuthenticated]);

This time the issue till remains the same, but before getBalance() is excuted, I manually get the isweb3enabled value, and it logs “true”, then when getBalance() is excuted, it logs ‘false’, so the isweb3anabled is actually true, but when the function executes it is false, I don’t understand this now, anyone know how to solve this ?

Hey @tigerkev

Setting timers is a bad practise. One of the possible solutions is to create 2 useEffects:

import { useMoralis } from "react-moralis";
import { useEffect, useState } from "react";
function App() {
  const { authenticate, isAuthenticated, user, logout, Moralis } = useMoralis();
  const { enableWeb3, isWeb3Enabled, web3 } = useMoralis();
  const [balance, setBalance] = useState("loading");

  function getBalance() {
    if (isWeb3Enabled)
      web3.eth
        .getBalance(user.get("ethAddress"))
        .then((res) => setBalance(res));
    console.log("web3 is enabled :", isWeb3Enabled);
  }

  useEffect(() => {
    if (isAuthenticated) {
      enableWeb3();
    }
  }, [isAuthenticated]);

  useEffect(() => {
    if (isWeb3Enabled) {
      getBalance();
    }
  }, [isWeb3Enabled]);

  return (
    <div className="App">
      <button onClick={() => authenticate()}>login</button>
      <button onClick={() => console.log("web3 is enabled: ", isWeb3Enabled)}>
        web3State
      </button>
      {isAuthenticated && <button onClick={() => logout()}>logout</button>}
      {isAuthenticated && <p>user id:{user.id}</p>}
      <p>account balance:{balance}</p>
    </div>
  );
}

export default App;

Hope this will help you :man_mechanic:

@tigerkev
Why do you use web3 for getting balances instead of using Moralis.Web3.getERC20() (Docs).

In this case web3 will not be needed. It’s faster and easier

thanks for the help, I use web3 because I will need to call contract later to display contract states, so I just used it to display balance, by the way, do you know why the isWeb3enabled value is actually true, but when the function executes, the isWeb3enabled value inside the function is false that I describe above ? I don’t understand how could this happen, thanks!

Hey @tigerkev

It’s becuase of your code logic. If you try this code:

function getBalance() {
    if (isWeb3Enabled)
      web3.eth
        .getBalance(user.get("ethAddress"))
        .then((res) => setBalance(res))
        .then(() => {
          console.log("web3 is enabled :", isWeb3Enabled);
        });
  }

You will not see console.log("web3 is enabled :", isWeb3Enabled) in the console because web3 isn’t Enabled at that moment.

Use two different useEffect hooks which I sent you before and all gonna be alright :sunglasses:

@tigerkev

function getBalance() {
   if (isWeb3Enabled)
     web3.eth
       .getBalance(user.get("ethAddress"))
       .then((res) => setBalance(res));
   console.log("web3 is enabled :", isWeb3Enabled);
 }

Is not the same:

 function getBalance() {
    if (isWeb3Enabled) {
      web3.eth.getBalance(user.get("ethAddress"))
        .then((res) => setBalance(res));
    console.log("web3 is enabled :", isWeb3Enabled);
  }
}

I see, thanks Yomoo, I am able to get it working through your code now.

1 Like