1

I'm trying to create 2d array of different types, one of the users have suggested to use struct within a struct method -> 2d array of different types?

Now I run into problem how to display it in my front end.

So here are my 2 structs:

 struct Pvote {
      address voter;
      string comment;

  }

    struct Project{
        uint id;
         int votes;
         address creator;
         string name;
        string decryption;
        string website;
        string imageLink;
        Pvote[] pvote;
       mapping(address => bool) voted;
    }
 Project[] public projects;

Now I Display Project array of a struct using fill().map() method like so:

  const projectsList = await Promise.all(
      Array(parseInt(getProjects))
      .fill()
      .map((element, index)=> {
        return Contract.methods.projects(index).call()
      }));

and this works perfectly

Now I want to display pvote[] array of structs. So I have created method in solidty to help me get it out of the 1st struct

  function getPvoteStruct (uint index, uint index2 ) public view returns(address,string){
           Project memory project = projects[index];
           return(project.pvote[index2].voter, 
           project.pvote[index2].comment);
       }

This works perfect in Remix, however when I'm trying to call this method from react:

const pVotesList = await Contract.methods.getPvoteStruct(0,0)
console.log(pVotesList)

It gives me what looks like abi of the contract, I have no idea why: *Yes I did make sure that there is a project at index 0 and that there is vote struct at vote array index 0.

{ call: { [Function: bound _executeMethod] request: [Function: bound _executeMethod] },
  send: { [Function: bound _executeMethod] request: [Function: bound _executeMethod] },
  encodeABI: [Function: bound _encodeMethodABI],
  estimateGas: [Function: bound _executeMethod],
  arguments: [ 0, 0 ],
  _method:
   { constant: true,
     inputs: [ [Object], [Object] ],
     name: 'getPvoteStruct',
     outputs: [ [Object], [Object] ],
     payable: false,
     stateMutability: 'view',
     type: 'function',
     signature: '0x7b76417a' },
  _parent:
   Contract {
     currentProvider: [Getter/Setter],
     _requestManager: RequestManager { provider: [Object], providers: [Object], subscriptions: {} },
     givenProvider: null,
     providers:
      { WebsocketProvider: [Function: WebsocketProvider],
        HttpProvider: [Function: HttpProvider],
        IpcProvider: [Function: IpcProvider] },
     _provider:
      HttpProvider {
        host: 'https://rinkeby.infura.io/QqWsfQ60KqF4HCDRrP6I',
        timeout: 0,
        connected: true,
        headers: undefined },
     setProvider: [Function],
     BatchRequest: [Function: bound Batch],
     extend:
      { [Function: ex]
        formatters: [Object],
        utils: [Object],
        Method: [Function: Method] },
     clearSubscriptions: [Function],
     options: { address: [Getter/Setter], jsonInterface: [Getter/Setter] },
     defaultAccount: [Getter/Setter],
     defaultBlock: [Getter/Setter],
     methods:
      { projects: [Function: bound _createTxObject],
        '0x107046bd': [Function: bound _createTxObject],
        'projects(uint256)': [Function: bound _createTxObject],
        getNvote: [Function: bound _createTxObject],
        '0x192e17cc': [Function: bound _createTxObject],
        'getNvote(uint256)': [Function: bound _createTxObject],
        withdraw: [Function: bound _createTxObject],
        '0x3ccfd60b': [Function: bound _createTxObject],
        'withdraw()': [Function: bound _createTxObject],
        remove: [Function: bound _createTxObject],
        '0x4cc82215': [Function: bound _createTxObject],
        'remove(uint256)': [Function: bound _createTxObject],
        getPvoteStruct: [Function: bound _createTxObject],
        '0x7b76417a': [Function: bound _createTxObject],
        'getPvoteStruct(uint256,uint256)': [Function: bound _createTxObject],
        getNumberOfvoters: [Function: bound _createTxObject],
        '0x870b9dc9': [Function: bound _createTxObject],
        'getNumberOfvoters()': [Function: bound _createTxObject],
        getOwner: [Function: bound _createTxObject],
        '0x893d20e8': [Function: bound _createTxObject],
        'getOwner()': [Function: bound _createTxObject],
        addNewProject: [Function: bound _createTxObject],
        '0xab508964': [Function: bound _createTxObject],
        'addNewProject(string,string,string,string)': [Function: bound _createTxObject],
        getPvote: [Function: bound _createTxObject],
        '0xb7409fcf': [Function: bound _createTxObject],
        'getPvote(uint256)': [Function: bound _createTxObject],
        temppvote: [Function: bound _createTxObject],
        '0xbb35e234': [Function: bound _createTxObject],
        'temppvote(uint256)': [Function: bound _createTxObject],
        getCost: [Function: bound _createTxObject],
        '0xbd3e19d4': [Function: bound _createTxObject],
        'getCost()': [Function: bound _createTxObject],
        upVote: [Function: bound _createTxObject],
        '0xc99d8eb8': [Function: bound _createTxObject],
        'upVote(uint256,string)': [Function: bound _createTxObject],
        change_cost: [Function: bound _createTxObject],
        '0xc9bae9bc': [Function: bound _createTxObject],
        'change_cost(uint256,uint256)': [Function: bound _createTxObject],
        getProjects: [Function: bound _createTxObject],
        '0xdcc60128': [Function: bound _createTxObject],
        'getProjects()': [Function: bound _createTxObject],
        downVote: [Function: bound _createTxObject],
        '0xe3ea5ded': [Function: bound _createTxObject],
        'downVote(uint256,string)': [Function: bound _createTxObject],
        editProject: [Function: bound _createTxObject],
        '0xe41c5f6f': [Function: bound _createTxObject],
        'editProject(uint256,string,string,string,string)': [Function: bound _createTxObject] },
     events: { allEvents: [Function: bound ] },
     _address: '0x2b4Ad5532919A8fEB7bB0E555842d893C0b1F148',
     _jsonInterface:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  _ethAccounts:
   Accounts {
     currentProvider: [Getter/Setter],
     _requestManager: RequestManager { provider: [Object], providers: [Object], subscriptions: {} },
     givenProvider: null,
     providers:
      { WebsocketProvider: [Function: WebsocketProvider],
        HttpProvider: [Function: HttpProvider],
        IpcProvider: [Function: IpcProvider] },
     _provider:
      HttpProvider {
        host: 'https://rinkeby.infura.io/MYAPI',
        timeout: 0,
        connected: true,
        headers: undefined },
     setProvider: [Function],
     _ethereumCall:
      { getId: [Object],
        getGasPrice: [Object],
        getTransactionCount: [Object] },
     wallet:
      Wallet {
        _accounts: [Circular],
        length: 0,
        defaultKeyName: 'web3js_wallet' } } } 
4

I think you should use

await Contract.methods.getPvoteStruct(0,0).call()

Also returning arrays from structs is a pain. See web3js.readthedocs.io/en/1.0/web3-eth-contract.html#id12

2

Lol seems like I forgot to add .call() at the end of const pVotesList = await Contract.methods.getPvoteStruct(0,0) Thanks grandfleet -> https://ethereum.stackexchange.com/users/44781/grandfleet for the anwser

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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