Solidity Truffle Test – How to Log Struct Member in Truffle Test

bignumbersoliditytruffleweb3js

Contract :

mapping (bytes32 => MyStruct) public myMapping;

  struct  MyStruct {
      uint256 myMember;
      uint256 someOtherMember;
  }

Test (Truffle)

This works:

let myStructResult = await this.contract.myMapping(id);
console.log(myStructResult);

But logs unfamiliar output (I'm not too solid on BN lib):

    Result {
  '0': '0x0000000000000000000000000000000000000000',
  '1': BN {
    negative: 0,
    words: [ 5, <1 empty item> ],
    length: 1,
    red: null
  },
  myMember: BN {
    negative: 0,
    words: [ 5, <1 empty item> ],
    length: 1,
    red: null
    },
   someOtherMember: BN {
    negative: 0,
    words: [ 5, <1 empty item> ],
    length: 1,
    red: null},

I see the value I want to log myMember, along with a few integer keys for which I don't understand their purpose

So I go:

let myMemberResult = await this.contract.myMapping(id).myMember;
let myMemberResultToNum = myMemberResult.toNumber()     
console.log(myMemberResult)
Result: undefined
console.log(myMemberResultToNum)
Result: cannot read property 'toNumber' of undefined

Why can I log the struct, but I can't log one of its members?

Best Answer

In:

let myMemberResult = await this.contract.myMapping(id).myMember;

The this.contract.myMapping(id).myMember part is executed before the await part.

You can fix it by adding parenthesis:

let myMemberResult = (await this.contract.myMapping(id)).myMember;

By the way, you could have easily concluded that from the experiment described in your own comment below the question.

As a side note, I would advise against converting BN to Number, since the latter is bound by Number.MAX_SAFE_INTEGER (2 ^ 53 - 1).

If you want to print it as a plain decimal number, then simply use myMemberResult.toString(), or better yet (in order to avoid scientific notation for extremely large values) - myMemberResult.toFixed().

Related Topic