0

I'm trying to create a web api function with NodeJS and Express, retrieving data from private ethereum blockchain.

The problem is that the method mytoken.tokenOfOwnerByIndex... is async method in loop but want to wait all results until done and let the function returns tokenIds as a result.

I tried to use async/await but don't know how to use them properly.

Here is the snippet of my current code:

app.get("/get", function(req, res, next){

  var Web3 = require('web3');
  var BigNumber = require('bignumber.js');

  Web3.providers.HttpProvider.prototype.sendAsync = Web3.providers.HttpProvider.prototype.send;
  var web3 = new Web3();
  web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));

  var contract = require("truffle-contract");
  var contractJson = require("./build/contracts/MyToken.json");
  var MyToken = contract(contractJson);
  MyToken.setProvider(web3.currentProvider);
  var tokenIds = [];
  MyToken.deployed().then(function(mytoken) {
    var account0 = web3.eth.accounts[0];
    mytoken.balanceOf(accounts0).then(function(balance){
      var x = balance.toNumber();
      for (i = 0; i < x; i++){
        mytoken.tokenOfOwnerByIndex(account0,0).then(function(tokenId){
          var y = tokenId.toNumber();
          tokenIds.push(y);
        });
      }
      res.json(tokenIds);
    });
  });
});

Can anyone guide me or give me the clue?

raimtoon
  • 725
  • 1
  • 11
  • 27
  • 1
    I can't see the necessary of changing the function into async-await form. What's the error do you have? Or you want to await them all together by `Promise.all()`? – MT-FreeHK Sep 13 '18 at 01:52
  • You saved my day! – raimtoon Sep 13 '18 at 03:46
  • I think you get it. That's related, https://stackoverflow.com/questions/52219013/why-i-can-not-push-value-to-array-outside-of-function/52220372#52220372 , I think I made a pretty easy example for complicated form of promise.all already. – MT-FreeHK Sep 13 '18 at 03:55

1 Answers1

1

I think in such cases library like Bluebird is really helpful. When working with iterables and promises you can use Bluebird's map() method (map).

Since you have a number here (var x) and not iterable you could do something like this

var Promise = require('bluebird);

var x = balance.toNumber();
var promises = []; 
for (i = 0; i < x; i++){
   promises.push(mytoken.tokenOfOwnerByIndex(account0,0));
});

Promise.all(promises).then(function(results) {
   //do something
});

You can refer to the Bluebird docs for more information

zerosand1s
  • 750
  • 1
  • 8
  • 23