EatTheBlocks Forum

Multisig front-end hangs on "Loading..."

Hi Julien, I’m having a strange issue running the frontend of the multisig project. When I use chrome dev tools to step through the code the issue goes away and the front-end loads as expected. But if I let the page load normally it gets stuck on waiting for web3 or something (Loading…). Thanks in advance for your help! Here is my code:

import React, { useEffect, useState } from “react”;
import Multisig from “./contracts/Multisig.json”;
import Web3 from “web3”;

const App = () => {
const [web3, setWeb3] = useState(undefined);
const [accounts, setAccounts] = useState(undefined);
const [contract, setContract] = useState(undefined);
const [balance, setBalance] = useState(undefined);
const [currentTransfer, setCurrentTransfer] = useState(undefined);
const [quorum, setQuorum] = useState(undefined);

useEffect(() => {
const init = async () => {
const web3 = await getWeb3();
setWeb3(web3);

  const accounts = await web3.eth.getAccounts();
  setAccounts(accounts);

  const networkId = await web3.eth.net.getId();
  const deployedNetwork = Multisig.networks[networkId];
  const contract = new web3.eth.Contract(
    Multisig.abi,
    deployedNetwork && deployedNetwork.address
  );
  setContract(contract);

  const quorum = await contract.methods.quorum().call();
  setQuorum(quorum);

  if (window.ethereum)
    window.ethereum.on("accountsChanged", (accounts) => {
      setAccounts(accounts);
    });
};
init();

}, []);

useEffect(() => {
const update = async () => {
await updateBalance();
await updateCurrentTransfer();
};
if (typeof contract !== “undefined” && typeof web3 !== “undefined”)
update();
}, [quorum, accounts, contract, web3]);

async function updateBalance() {
let balance = “0”;
console.log(“address”, contract.options.address);
try {
balance = (
await web3.eth.getBalance(contract.options.address)
).toString();
} catch (e) {
console.log(e.message);
}
setBalance(balance);
}

async function createTransfer(e) {
e.preventDefault();
const amount = e.target.elements[0].value;
const to = e.target.elements[1].value;
await contract.methods
.createTransfer(amount, to)
.send({ from: accounts[0] });
await updateCurrentTransfer();
}

async function approveTransfer() {
await contract.methods
.approveTransfer(currentTransfer.id)
.send({ from: accounts[0] });
await updateBalance();
await updateCurrentTransfer();
}

async function updateCurrentTransfer() {
const currentTransferId = (await contract.methods.nextId().call()) - 1;
if (currentTransferId >= 0) {
const currentTransfer = await contract.methods
.transfers(currentTransferId)
.call();
const alreadyApproved = await contract.methods
.approvals(accounts[0], currentTransferId)
.call();
setCurrentTransfer({ …currentTransfer, alreadyApproved });
}
}

if (!web3) {
return

Loading…
;
}

return (


<h1 className=“text-center” style={{ marginBottom: “0px” }}>
Multisig

<p style={{ margin: “0px” }}>
Balance: {balance} wei

<button
onClick={updateBalance}
style={{ border: “1px solid #aaa”, borderRadius: “10px” }}
>
Update
  {!currentTransfer || currentTransfer.approvals === quorum ? (
    <div className="row">
      <div className="col-sm-12">
        <h2 style={{ marginBottom: "0px" }}>Create transfer</h2>
        <form onSubmit={(e) => createTransfer(e)}>
          <div className="form-group">
            <input
              placeholder="Amount:"
              type="number"
              className="form-control"
              id="amount"
              style={{ border: "1px solid #aaa" }}
            />
          </div>
          <div className="form-group">
            <input
              placeholder="To: (address)"
              type="text"
              className="form-control"
              id="to"
              style={{ border: "1px solid #aaa" }}
            />
          </div>
          <button
            type="submit"
            className="btn btn-primary"
            style={{ border: "1px solid #aaa", borderRadius: "10px" }}
          >
            Submit
          </button>
        </form>
      </div>
    </div>
  ) : (
    <div className="row">
      <div className="col-sm-12">
        <h2>Approve transfer</h2>
        <ul>
          <li>TransferId: {currentTransfer.id}</li>
          <li>Amount: {currentTransfer.amount}</li>
          <li>Approvals: {currentTransfer.approvals}</li>
        </ul>
        {currentTransfer.alreadyApproved ? (
          "Awaiting other approvers..."
        ) : (
          <button
            type="submit"
            className="btn btn-primary"
            onClick={approveTransfer}
          >
            Approve
          </button>
        )}
      </div>
    </div>
  )}
</div>

);
};

const getWeb3 = () =>
new Promise((resolve, reject) => {
// Wait for loading completion to avoid race conditions with web3 injection timing.
window.addEventListener(“load”, async () => {
// Modern dapp browsers…
if (window.ethereum) {
const web3 = new Web3(window.ethereum);
try {
// Request account access if needed
await window.ethereum.enable();
// Acccounts now exposed
resolve(web3);
} catch (error) {
reject(error);
}
}
// Legacy dapp browsers…
else if (window.web3) {
// Use Mist/MetaMask’s provider.
const web3 = window.web3;
console.log(“Injected web3 detected.”);
resolve(web3);
}
// Fallback to localhost; use dev console port by default…
else {
const provider = new Web3.providers.HttpProvider(
http://127.0.0.1:8545
);
const web3 = new Web3(provider);
console.log(“No web3 instance injected, using Local web3.”);
resolve(web3);
}
});
});

export default App;

/*
return (
<DrizzleContext.Provider drizzle={drizzle}>
<DrizzleContext.Consumer>
{drizzleContext => {
const { drizzle, drizzleState, initialized } = drizzleContext;

      if (!initialized) {
        return "Loading..."
      }

      return (
        <MyComponent drizzle={drizzle} drizzleState={drizzleState} />
      )
    }}
  </DrizzleContext.Consumer>
</DrizzleContext.Provider>

);
*/

Is this Multisig from Dapp 30? It seems so.

I compared your code with the one of the repo and its not exactly the same.

Can you try with the exact code of the repo and tell me if it still does not work?

Ok I reverted back to the code in gitlab and still getting that error.

I can hit the breakpoint I set on window.addEventListener in the getWeb3 function but it doesnt look like the body of that function is ever executed.

When I check the react debugger none of the state variables are defined so !web3 == true and thats why I’m seeing “Loading…” But why would the event listener not fire?

If I debug and step through each line of init() though everything works :tired_face:

SOS

I’m using the same code for my Dex frontend and it works there so this issue is effectively closed. Thanks!

1 Like

ok awesome :slight_smile: I just tried the code of the git repo on my side and it worked.

I had faced the same issue, had commented out the event listener call and then it worked.

1 Like