1

So I have been wondering how to return an array from a struct in drizzle, I can make multiple calls using web3, but it is kinda complex and would like a simpler approach. A simplified contract is listed below, the function to add new files is removed.

contract FileList {

   /// @dev struct that contains unique link to image (via IPFS), serial Id, and timestamp
   struct File {
      uint256 id;
      string ipfshash;
      bytes32 filename;
      bytes32[5] tags;
      address owner;
      uint256 timestamp;
   }
   uint256 public constant maxAmountOfFiles = 1000;
   // Owner => files
   mapping(address => File[maxAmountOfFiles]) public files;
   // Owner => last files id
   mapping(address => uint256) public lastIds;
   // consider mapping hash to set of tags

   /// @dev return the tags for a specific file 
   /// @param owner --- address of person who uploaded the file 
   /// @param _index --- the file desired, (first file uploaded, second , etc ...)
   function getFileTags(address owner, uint256 _index) external view returns (bytes32[5]) {
       return files[owner][_index].tags;
  }

}

To grab the table from the front-end

let table = []
this.drizzle.contracts.FileList.methods.lastIds(this.state.fileOwnerAddress).call()
.then((lastIds) => {
    // eslint-disable-line no-loop-func
   for (let i = 0; i < lastIds; i++) {
     this.drizzle.contracts.FileList.methods.files(this.state.fileOwnerAddress,i).call()
     .then((fileItem) => {
       // add file item to table, missing tags
       fileItem.filename = this.drizzle.web3.utils.hexToUtf8(fileItem.filename)
       fileItem.timestamp = this.timeConverter(fileItem.timestamp)
       /** Can't return bytes from struct array, maybe split this into into another loop?. */
       this.drizzle.contracts.FileList.methods.getFileTags(this.state.fileOwnerAddress,i).call()
       .then((tags) => {
          // console.log(tags)
          // convert all non 0 bytes tag fields to hex
          for (var j=0; j < 5; j++) {
            if (tags[j] !== '0x0000000000000000000000000000000000000000000000000000000000000000') {
              // console.log(tags[j])
              tags[j] = this.drizzle.web3.utils.hexToUtf8(tags[j])
            } else {
              // console.log(tags[j])
              tags[j] = 'N/A'
            }
          }
          fileItem.tags = tags
          console.log(tags)
       })
       // console.log(fileItem)
       // add fileItem to table
       table.push(fileItem)
     });
   }

If anyone can give suggestions on how to improve my code or somehow load this data in drizzle (right now the bytes32 array is not being returned), that would be appreciated

0

I think this is more of a basic javascript problem then anything else... I would take a look at es6 some es6 array methods such as forEeach()

https://www.tutorialspoint.com/es6/es6_arrays.htm

Essentially what should be done here is creating some small functions to handle the formatting of data. You can then compose your different functions into something a bit cleaner.

  • See I think forEach won't work as returning all the data from the blockchain is illadvisable. Especially with a hardcoded limit of 1000. In particular I was wondering if anyone knew how to use the drizzle library to simplify the process. – GrandFleet Oct 25 '18 at 14:54
  • maybe that will help for the tag array – GrandFleet Oct 25 '18 at 17:43

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.