0

I tried to get the data of the struct by its mapping string, but I got undefined in innerhtml and get following result in the html console log:

enter image description here

however I can search the data from the Remix ABI, anyone know how to retrieve the data by web3?

my web3 version is 1.5.1, and the entire code is here

this is my solidity code:

pragma solidity >=0.7.0 <0.9.0;

contract Storage{

    string b = "calculation a";
    struct UserInfo {
        string time;
        string source;
        uint emission;
    }
    mapping (string => UserInfo) users;

    the function of saving data is ignored
    
    function search(string memory input_source) public view returns (uint, string memory) {
        return (users[input_source].emission, users[input_source].time);
    }
}

and this is the javascript

// Initialize Web3
var web3 = new Web3('http://localhost:7545');

// Set Account
web3.eth.defaultAccount = '0x16E15b184F39c4fBE1A4B29052CE018c5748610B';

// Set Contract Abi
var ABI = [abi];

// Set Contract Address
var contractAddress = 'my addr'; // Add Your Contract address here!!!

// Set the Contract
var contract = new web3.eth.Contract(ABI, contractAddress);

//get the formCarbonEmission data
function showCompanyResultLineChart() {
  const input_company = document.getElementById("company");//the "company" is the id of the button"
  const companyResultLineChart = document.getElementById("companyResultLineChart");
  //the "companyResultLineChart" is the id for displaying the data
  
  const result = contract.methods.search(input_company).call({from:web3.eth.defaultAddress});
  console.log(result)
  companyResultLineChart.innerHTML = "the " + input_company.value + 
" factory created " + result[0] + " tons of CO2 in " + result[1];//the result[] show "undefined".
}

1 Answer 1

0

Reading from the Ethereum blockchain is asynchronous. You need to either define showCompanyResultLineChart() as an async function and await the read method call as in:

async function showCompanyResultLineChart() {
...
  
  const result = await contract.methods.search(input_company).call({from:web3.eth.defaultAddress});
...
}

Or, use the then(..) syntax and place all result-dependent lines in the callback function as in:

function showCompanyResultLineChart() {
...
  
  contract.methods.search(input_company).call({from:web3.eth.defaultAddress}).then((result) => {
  console.log(result)
  companyResultLineChart.innerHTML = "the " + input_company.value + 
" factory created " + result[0] + " tons of CO2 in " + result[1];//the result[] show "undefined".
});
}
5
  • thanks for your solution. But now I find out that it didn't show the result I input, it shows null. Do u have any idea of this? (I can get the result in remix)
    – ginwei
    Aug 17, 2021 at 1:37
  • @ginwei maybe try without the {from:..} part? It's not really needed for a read call. Aug 17, 2021 at 8:01
  • I've tried it and still not work. I've google the solution, but none of the solution I found work for it...
    – ginwei
    Aug 18, 2021 at 1:02
  • I can return the data in the function I save data, but I can't do it in the search function. So it seems that the mapping struct can't passing through different function. That's may be the point for solution.
    – ginwei
    Aug 19, 2021 at 15:49
  • and i also find this: problem. But i still don't know how to solve it.
    – ginwei
    Aug 19, 2021 at 15:52

Your Answer

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

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