I'm using web3js (via Truffle) to make a call to a contract, to access a struct in a mapping.

mapping (bytes32 => entry) public entries; 

struct entry {
    Mode status;
    Deed deed;
    uint registrationDate;
    uint value;
    uint highestBid;

Here is the call:

var myEntry = Registrar.deployed().entries.call("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4af")

Which returns:

[ { [String: '1'] s: 1, e: 0, c: [ 1 ] },
  { [String: '1482956489'] s: 1, e: 9, c: [ 1482956489 ] },
  { [String: '0'] s: 1, e: 0, c: [ 0 ] },
  { [String: '0'] s: 1, e: 0, c: [ 0 ] } ]

Which looks to me like an array, but:

truffle(default)> myEntry;
// [ { [String: '1'] s: 1, e: 0, c: [ 1 ] },
//   '0x0000000000000000000000000000000000000000',
//   { [String: '1482956489'] s: 1, e: 9, c: [ 1482956489 ] },
//   { [String: '0'] s: 1, e: 0, c: [ 0 ] },
//   { [String: '0'] s: 1, e: 0, c: [ 0 ] } ]

truffle(default)> myEntry[0];
// undefined

truffle(default)> myEntry[1];
// undefined

truffle(default)> typeof(myEntry);

How can I access any of the properties (members?) of this object?

Note: I can't update the contract, it's the ENS' Initial Registrar.


The issue is here:

var myEntry = Registrar.deployed().entries.call("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4af")

.call() returns a Promise. The Truffle console is "smart" and knows when you write an expression that returns a Promise[1]. When this happens, it will automatically resolve it for you and print out the result, or print out any error that occurred. What you're seeing in the output is the printed out result, and not the actual value of myEntry. Instead, what you need to do is the following.

truffle(default)> var myEntry;
truffle(default)> Registrar.deployed().entries.call(...).then(function(result) {myEntry = result;})
truffle(default)> myEntry

It's a little bit of a hassle but such is life with a console and promise objects.

[1] Note that setting a variable to a Promise in the Truffle console is still interpreted as an expression whose result is the value of the variable.

| improve this answer | |
  • Thanks! The callback pattern solves my problem. I understand your meaning, but one thing that might be worth noting is that this behavior isn't isolated to .call(); ie. Registrar.deployed().entries(...) behaves in the exact same way. – maurelian Nov 30 '16 at 22:32
  • 1
    Awesome to finally have this somewhere, Tim! I spent hours in the docs and examples trying to understand this- Would it be possible to have this in the 'Interacting with your contracts' section of the docs? Promise objects and their returns are definitely confusing, particularly for those of us who don't come to Solidity from Javascript. – emunsing Jul 8 '17 at 22:18
  • Also, if it's possible to distinguish between the actual object and the static promise output, that would be great- in both examples, typeof(myEntry) is object making it difficult to troubleshoot where any errors are. – emunsing Jul 8 '17 at 22:28
  • cant find this in the documentation. In particular how to interact with public variables of contracts when these are arrays and mappings – pepo Oct 22 '17 at 18:17
  • @emunsing, are you able to access the properties of the myEntry struct as myEntry.value for instance? I am still receiving this weird array instead of a nice javascript with properties named as the structure properties – pepo Oct 22 '17 at 18:23

When you want to access Promise object field you could use then such as :

If you call

var myEntry = Registrar.deployed().entries.call("0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4af")

Then you could access real object myEntryObject :

var myEntryObject
myEntry.then(a => myEntryObject = a)
| improve this answer | |

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.