ginwei
ginwei

Reputation: 55

the mapping struct return null by web3

Now I try to do the solidity to save the struct data, and retrieve the data by mapping string in web3 interface.

Now I've finished the data saving part, and I can get the data in my Remix API, but if I wanna get the data by web3, it'll return null as following:

enter image description here

the version of the web3 is 1.3.4. I once tried whether I can return the data in the function of saving data and it worked, thus I guess that the data isn't shared by functions in web3...

and I found out this problem, but I still can't get the solution.

the following is the code:

pragma solidity >=0.7.0 <0.9.0;

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

    function saveData(string memory input_time, string memory input_source, string memory input_mycalculate, uint input_material) public{
        users[input_source].time = input_time;
        if (keccak256(abi.encodePacked(input_mycalculate)) == keccak256(abi.encodePacked(b)))
            users[input_source].emission = input_material * 3 / 2;
        else
            users[input_source].emission = input_material * 5 / 2;
    }
    
    function search(string memory input_source) public view returns (UserInfo memory) {
        return users[input_source];
    }
} 

and the following is the js code to show the data:

contract.methods.search(input_company).call({from:web3.eth.defaultAddress})
  .then((result) => {
        console.log(result)
        companyResultLineChart.innerHTML += result[0] + result[1]
  })

Upvotes: 1

Views: 598

Answers (1)

Peteris
Peteris

Reputation: 418

It should be an timing issue. It is a asynchronous JavaScript code so you have to use ".then" or await. In Your code example you are using ".then". I used saveData function with "60sec", "test_src", "calc", "10" for testing purpose. So below code:

console.log("------ before then ------ ")
let innerHTML = "HTML "
contract.methods.search("test_src").call().then((result) => {
   console.log(innerHTML)
   innerHTML += result[0] + result[1] 
   console.log(result)
   console.log(innerHTML)
   
})

console.log("------ after then ------ ")

will type in console:

------ before then ------ 
------ after then ------ 
HTML 
[ "60sec", "25" ]
HTML 60sec25

Code with await:

console.log("------ before await ------ ")
let innerHTML2 = "HTML "
let result_async = await contract.methods.search("test_src").call();
console.log(innerHTML2)
innerHTML2 += result_async[0] + result_async[1] 
console.log(result_async)
console.log(innerHTML2)
console.log("------ after await ------ ")

will type in console:

------ before await ------ 
HTML 
[ "60sec", "25" ]
HTML 60sec25
------ after await ------ 

Upvotes: 1

Related Questions