2

Using Web3.js, how do I call a function on multiple instances of a contract and then store their results in an array? I've tried .map and .forEach, but they don't return the objects I expected.

I am able to get a desirable result when I call the function on one instance:

let giftStats = await SmartGift(
        '0xbb6810057e1D82deE83A981b002F2E0C60293a27'
    )
        .methods.getGiftStats()
        .call()



console.log(giftStats)

Result { '0': '0xfAA7541C5cBe22E4518736D2b5fC34D07347eE45', '1': '0x0000000000000000000000000000000000000000', '2': '0x0000000000000000000000000000000000000000', '3': '0', '4': '0', '5': '0', '6': '100', '7': '0', '8': false, '9': false, '10': '' }

I'm looking for a method that enables me to store two objects like the one above in an array. But when I try to call map() or forEach() on an array of addresses, the resulting array is not what I'd expect.

ATTEMPT 1: .map( )

const recipientGifts = ['0xAEaadCd9499127Ae0826aC2E918372927E4B55D4','0xbb6810057e1D82deE83A981b002F2E0C60293a27']    
let giftStats = await recipientGifts.map((address) => {
JSON.stringify(
    SmartGift(address)
    .methods.getGiftStats()
    .call()
)
console.log(giftStats)  

[ undefined, undefined ]

ATTEMPT 2: .forEach( )

const recipientGifts = ['0xAEaadCd9499127Ae0826aC2E918372927E4B55D4','0xbb6810057e1D82deE83A981b002F2E0C60293a27']  
let giftStats = []
await recipientGifts.forEach((address) =>giftStats.push(SmartGift(address)  
    .methods.getGiftStats() 
    .call() ))

console.log(giftStats)

[ Promise { _bitField: 0, _fulfillmentHandler0: undefined, _rejectionHandler0: undefined, _promise0: undefined, _receiver0: undefined }, Promise { _bitField: 0, _fulfillmentHandler0: undefined, _rejectionHandler0: undefined, _promise0: undefined, _receiver0: undefined } ]

0

The second method is pretty close but you should try to put the await inside the forEach since that would return a promise

await recipientGifts.forEach(async(address) => giftStats.push(await SmartGift(address)  
    .methods.getGiftStats() 
    .call() ))
  • I just tried this, but it returns an empty array. – concreteWall Mar 22 '18 at 14:09
  • I think probably forEach doesn't support promises. Just use a normal loop instead, gonna be ok – mirg Mar 22 '18 at 14:17
  • Yeah, after incorporating your suggestion, I replaced the .forEach( ) with a for loop, and it works! Thanks! – concreteWall Mar 22 '18 at 14:17
0

I originally wanted to solve this using only functional programming, avoiding loops. But I got it to work using a for loop.

let giftStats = []
    for (let i = 0; i < recipientGifts.length; i++) {
        giftStats.push(
            await SmartGift(
                recipientGifts[i])
                .methods.getGiftStats()
                .call()
        )
    }

console.log(giftStats)
[ Result { '0': '0xfAA7541C5cBe22E4518736D2b5fC34D07347eE45', '1': '0x0000000000000000000000000000000000000000', '2': '0x0000000000000000000000000000000000000000', '3': '0', '4': '0', '5': '0', '6': '5000', '7': '0', '8': false, '9': false, '10': '' }, Result { '0': '0xfAA7541C5cBe22E4518736D2b5fC34D07347eE45', '1': '0x0000000000000000000000000000000000000000', '2': '0x0000000000000000000000000000000000000000', '3': '0', '4': '0', '5': '0', '6': '100', '7': '0', '8': false, '9': false, '10': '' } ]

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.