When I return a string array with web3 I don't get the original array as expected, but rather I get an array of the same size, with the index off by one.
So instead of ["One","Two","Three"]
I get ["","One","Two"]
I am certain my contract is correct, because when I call the function on remix.ethereum.org I correctly get ["One","Two","Three"]
as the return value.
Contract:
pragma experimental ABIEncoderV2;
pragma solidity ^0.5.0;
contract ProblemDemo {
string[] private myStringArray;
constructor () public {
myStringArray.push("One");
myStringArray.push("Two");
myStringArray.push("Three");
}
function addToMyStringArray (string memory newEntry) public {
myStringArray.push(newEntry);
}
function getMyStringArray () public view returns (string[] memory) {
return myStringArray;
}
}
Simple HTML displaying the issue:
<!DOCTYPE html>
<html lang="en">
<head></head>
<body>
<script src="https://github.com/ethereum/web3.js/blob/develop/dist/web3.min.js" type="text"></script>
<h1>My Test</h1>
<div id="output"></div>
<button id="button">Click</button>
<script>
window.addEventListener('load', function() {
if(typeof web3 !== undefined) web3js = new Web3(web3.currentProvider);
document.getElementById("button").addEventListener("click", function() {
getMyStringArray();
}, function(error, result){}, false);
});
var contractInstance;
var contractABI = [
{
"constant": false,
"inputs": [
{
"name": "newEntry",
"type": "string"
}
],
"name": "addToMyStringArray",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "getMyStringArray",
"outputs": [
{
"name": "",
"type": "string[]"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
}
];
var contractAddress = "0x8fcb440a8ba9df8ea91493be3bd27ab562d04386";
<!-- Contract Address is on the Rinkeby Test Network -->
contractInstance = web3.eth.contract(contractABI).at(contractAddress);
function getMyStringArray() {
contractInstance.getMyStringArray(function(error, result){
document.getElementById("output").innerHTML = result;
});
}
</script>
</body>
</html>