0

I have an Array of orders and want to loop inside the array and call an async function to check each order and then render the array inside the dom.dow is my code

I try to create an array outside of mapping and push valid orders to the array but when I log the array its empty

renderTrades = () => {
    const { trades } = this.props;
    const contractWrappers = new ContractWrappers(web3Wrapper._provider, { networkId: KOVAN_NETWORK_ID });
    const _trade = [];
    trades.map((trade, index) => {
        contractWrappers.exchange.getOrderInfoAsync(trade.order)
            .then((val) => {
                if (val.orderStatus == 5) {
                    _trade.push(<TradeRow0x key={index} />);
                }
            });
    });
    return _trade;
};

I want to push valid orders to the array and render it into the dom

  • 5
    Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Jared Smith Jan 02 '19 at 12:24
  • You'll have to use something like [Promise.all](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) – Jared Smith Jan 02 '19 at 12:25
  • @JaredSmith can you provide a sample for my situation? – Amirhosein Rajabi Jan 02 '19 at 12:51

1 Answers1

1

Can be achieved using Promise.all() to await for all of your promises to resolve before returning your required JSX.

// map all of your trades to promises
const tradesPromises = trades.map(trade => contractWrappers.exchange.getOrderInfoAsync(trade.order))

Promise.all(tradesPromises).then(res => {
  // all of your promises have now resolved, so you can return your jsx as required.
  const mappedTrades = res.map((value, index) => {
    return value.orderStatus === 5 ? <TradeRow key={index} /> : null
  })

  // now you will be able to log these out and see what you are 
  // expecting as the promises will all have resolved.
  console.log(mappedTrades);
})

See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all for an in-depth description and example of Promise.all

Mark
  • 459
  • 2
  • 12
  • 1
    This seems to be the correct answer, but if the function is called inside React render function, it may not work. Async rendering is not a thing for most of us yet https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html – Apolo Jan 02 '19 at 13:03
  • @Apolo I use the function to set orders into the state and use the state inside the render but it sometimes works and sometimes not (also I'm using NextJs for server-side rendering) – Amirhosein Rajabi Jan 03 '19 at 08:57
  • that is a race condition, react render does not wait for the promise to resolve before it returns it's markup. For now any async operation should be done inside `componentDidMount`, you may want to display a loader until these operations are completed – Apolo Jan 03 '19 at 09:03