web3js – Resolve Web3 Error: No Synchronous Methods Without Callback Parameter

javascriptmetamasktruffle-boxweb3js

I try to load the Metamask Web3 object into my react/redux frontend. On page load i encounter the following error:

inpage.js:233 Uncaught Error: The MetaMask Web3 object does not support synchronous methods like eth_mining without a callback parameter. See https://github.com/MetaMask/faq/blob/master/DEVELOPERS.md#dizzy-all-async---think-of-metamask-as-a-light-client for details.
at MetamaskInpageProvider.send (inpage.js:233)
at s.send (inpage.js:14300)
at r.mining (inpage.js:14300)
at derez (<anonymous>:2:6079)
at derez (<anonymous>:2:6072)
at derez (<anonymous>:2:6072)
at derez (<anonymous>:2:6072)
at derez (<anonymous>:2:6072)
at derez (<anonymous>:2:6072)
at derez (<anonymous>:2:6072)

Here is the relevant code:

import store from '../'
import Web3 from 'web3'

export const WEB3_INITIALIZED = 'WEB3_INITIALIZED'
function web3Initialized(results) {
    return {
        type: WEB3_INITIALIZED,
        payload: results
    }
}

let getWeb3 = new Promise(function(resolve, reject) {
    // Wait for loading completion to avoid race conditions with web3 injection timing.
    window.addEventListener('load', function(dispatch) {
        var results
        var web3 = window.web3
        console.log(web3)

        // Checking if Web3 has been injected by the browser (Mist/MetaMask)
        if (typeof web3 !== 'undefined') {
            // Use Mist/MetaMask's provider.
            web3 = new Web3(web3.currentProvider)

            results = {
                web3Instance: web3
            }

            console.log('Injected web3 detected.');

            resolve(store.dispatch(web3Initialized(results)))
        } else {

            // Fallback to localhost if no web3 injection. We've configured this to
            // use the development console's port by default.
            var provider = new Web3.providers.HttpProvider('http://127.0.0.1:9545')

            web3 = new Web3(provider)

            results = {
                web3Instance: web3
            }

            console.log('No web3 instance injected, using Local web3.');

            resolve(store.dispatch(web3Initialized(results)))
        }
    })
})

export default getWeb3

This is taken straight from truffles react-redux box (https://github.com/truffle-box/react-auth-box)

It does not tell me where the error occurs, where the callback is missing. I'm a bit confused as i thought truffle boxes contain best practice code. What am i missing here?

Best Answer

This section of code is not where the error is coming from. That code just creates the web3 object. The error is from some piece of code that's using web3 to interact with a contract.

When you use web3 you can either do this

var res = myContract.function.call();

or

myContract.function.call(function (err, res) {
  //do stuff
})

The second method is better because the call is asynchronous -> even if it times out the whole app won't freeze up. Metamask goes further and blocks devs from even using the first option. Not all web3 calls can be async, for examble the number conversion functions are done instantly. But all calls interacting with contracts should be done async.

Related Topic