Asyn c вызов API в функции карты (React) - PullRequest
0 голосов
/ 27 февраля 2020

Таким образом, в настоящее время я работаю над проектом, в котором стоимость авуаров (список акций и их количество) данного пользователя должна быть рассчитана, когда пользователь попадает на страницу панели инструментов. В настоящее время я вызываю API через GET для каждого элемента в списке владений и вычисляю общую текущую стоимость этих акций. В конце я получаю тикер акций, текущую стоимость, сумму и сумму (сумма * текущая стоимость). Затем я хочу отобразить эти значения пользователю с помощью функции map в render ().

Изначально я попытался извлечь и рассчитать всю эту информацию в функции map в render, которая будет перебирать список владений. Тем не менее, я не смог заставить его даже скомпилироваться без ошибок, связанных с обещаниями, помещаемыми в JSX (я обрабатывал asyn c). Я понял, что могу просто вычислить список в componentDidMount (), хотя и выбрал это.

К сожалению, я все еще вижу проблемы, хотя на этот раз он компилируется. В componentDidMount () я выполняю следующее:

const holdings = store.getState().mainApp.portfolio.holdings;
var newHoldings = []
holdings.forEach(async element => {
  const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`);      
  let stockPrice = stock.data[0].price      
  let total = +stockPrice * +element.qty;
  newHoldings.push({
    ticker: element.ticker,
    qty: element.qty,
    price: stockPrice,
    totPrice: total
  })
});

this.setState({ activePortfolio: newHoldings })

Вот что я делаю в функции визуализации

{this.state.activePortfolio ? 
  // CONSOLE LOG HERE OF activePortfolio RETURNS THE CALCULATED LIST
  this.state.activePortfolio.map((value) => 
    // CONSOLE LOG HERE RETURNS NOTHING
    console.log(value)
    // <div>
    //   <p>{value.ticker} <span style={{right: '2vw', float: 'right'}}>{value.qty}x @ ${value.price}/ea</span></p>
    //   <p style={{float: 'right'}}> $ {value.totPrice}</p>
    // </div>
)
: 
  console.log("ERROR ACTIVE P")
}

В настоящее время функция карты просто регистрирует каждое значение в activePortfolio, но когда Я запускаю его, и есть запасы, которые ничего не регистрируют. Однако, как видно выше, он регистрирует список (если не повторяется). Кто-нибудь знает, что здесь происходит? Я просто скучаю по чему-то маленькому и основному c?

Спасибо, ребята!

РЕДАКТИРОВАТЬ ... (в свете комментария @ zero298)

    var promises = holdings.map(element => {
        return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
          let stockPrice = stock.data[0].price
          let total = +stockPrice * +element.qty;
          return ({
            ticker: element.ticker,
            qty: element.qty,
            price: stockPrice,
            totPrice: total
          });
        })
    })

    console.log(Promise.all(promises))
    Promise.all(promises).then(res => {
      newHoldings = res;
    });

Так что теперь, когда я устанавливаю новые владения в res (что, кстати, res правильно показывает значения массива при входе в систему), он все равно не может записать значение в функцию map в render (). Я что-то здесь не так делаю? Я все еще немного новичок в обещаниях.

РЕДАКТИРОВАТЬ 2 ... Хорошо! Так что спасибо @dave за помощь, а также @ zero298. В итоге я использовал комбинированное решение. Единственная проблема с вышеупомянутым редактированием заключалась в том, что я не сделал componentDidMount () функцией asyn c, и при этом я не вызывал await для функции Promise.all (). (совершенно не думал, что вы могли бы сделать это с помощью componentDidMount ()!) Вот фиксированное решение ...

async componentDidMount(){

    *... other init code ...*

    var promises = holdings.map(element => {
        return axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${element.ticker}`).then(stock => {
          let stockPrice = stock.data[0].price
          let total = +stockPrice * +element.qty;
          return ({
            ticker: element.ticker,
            qty: element.qty,
            price: stockPrice,
            totPrice: total
          });
        })
    })

    console.log(Promise.all(promises))
    await Promise.all(promises).then(res => {
      newHoldings = res;
    });
};

Большое спасибо, ребята, я очень ценю помощь!

1 Ответ

1 голос
/ 28 февраля 2020

Я думаю, вы можете просто захотеть сделать:

await Promise.all(promises).then(res => {
  newHoldings = res;
});

Если это не сработает, вы можете сделать это так:

for await (const holding of holdings) {
  const stock = await axios.get(`https://api.iextrading.com/1.0/tops/last?symbols=${holding.ticker}`);      
  let stockPrice = stock.data[0].price      
  let total = +stockPrice * +holding.qty;
  newHoldings.push({
    ticker: holding.ticker,
    qty: holding.qty,
    price: stockPrice,
    totPrice: total
  })
};

this.setState({ activePortfolio: newHoldings })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...