Объединение двух реагирующих API вместе, где вывод одного идет на вход второго.Использует Axios / Async - PullRequest
0 голосов
/ 01 января 2019

Использование React.

Я приложение, которое берет данные, которые были отправлены в строке поиска, и возвращает список идентификаторов.Я хочу взять эти идентификаторы и передать его через другой API.Однако я не уверен, как это сделать.Я просмотрел несколько других страниц на стеке, таких как , и , .Первый слишком расплывчатый, а второй имеет независимые вызовы API, которые выполняются последовательно.

Вот мой код:

import React from 'react'
import api1 from '../api/api1'

import SearchBar from './SearchBar'

class App extends React.Component {
    state = { cards: [],  new_cards: []}; 

    onSearchSubmit = async (term) => {
    const response = await api1.get("api/decks/" + term)
    this.setState({ cards: response.data.data.cards, })
    } 

  render () {
    return (<div className='ui container'>
      <SearchBar onSubmit={this.onSearchSubmit} />
      {/* <CardList cards={this.state.cards} /> */}
    </div>)
  }
}
export default App

Мой код примет первый API и передаствывод (список из 36 элементов) вплоть до компонента CardList.Однако список не полный, он должен быть списком списков (вы можете сказать, что я пришел с python).Сначала мне нужно вызвать другой API-интерфейс (локальный на моем компьютере), получить оставшиеся данные и затем передать новый список (из 36 списков) компоненту CardList.Второй API работает просто отлично сам по себе.У меня проблемы с их объединением.

Это мои мысли, но это не работает.1) создать новую функцию getCardStats 2) использовать функцию map для итерации по списку один и запустить вызов API.3) добавить вывод шага 2) в новый список 4) вернуть новый список 5) передать новый список в CardList

В первом списке 36 элементов, поэтому следующий API должен вызываться 36 раз,Я не знаю, каковы последствия того, что делать так много / мало.Нужно ли нам положить что-то, что ждет всех 36, чтобы закончить, или мы можем сделать их параллельно?

import React from 'react'
import api1 from '../api/api1'
import api2 from '../api/api2'

import SearchBar from './SearchBar'

class App extends React.Component {
    state = { cards: [] }; 

    onSearchSubmit = async (term) => {
    const response = await api1.get("api/decks/" + term)

    this.setState({ cards: response.data.. })
    this.getCardStats(this.state.cards)
    }        

    getCardStats = async (cards)=> {
      console.log('we are here')
      console.log(cards)
      const response = props.cards.map(card => {
          return await api2.get("api/cards/" + card)
      })
    }
    console.log('finished')
    console.log(response)
    this.setState({ new_cards: response.data.data.cards })

  render () {
    return (<div className='ui container'>
      <SearchBar onSubmit={this.onSearchSubmit} />
      {/* <CardList cards={this.state.new_cards} /> */}
    </div>)
  }
}
export default App

Мысли?

1 Ответ

0 голосов
/ 01 января 2019

Вызов Axios возвращает Promises, и я предполагаю, что ваши функции API используют его.Кажется, вы застряли на том, как работать с ними, то есть объединить их в цепочку, или запустить кучу и подождать, пока все они решатся.Надеюсь, я могу объяснить, как это сделать без промежуточного шага сохранения состояния.

import React from 'react'
import api1 from '../api/api1'
import api2 from '../api/api2'

import SearchBar from './SearchBar'

class App extends React.Component {
  state = { cards: null }; 

  onSearchSubmit = term => {
    api1.get("api/decks/" + term) // returns a resolved promise, which is 'then'-able
      .then(cards => {
        // now we can setup our next API call
        // create an array of them and use Promise.all()

        const cardRequests = cards.map(card => api2.get(`api/cards/${card}`));
        return Promise.all(cardRequests); // This Promise resolves when all individual promise resolve, or rejects if any single one rejects.
      })
      .then(allCardsResults => {
        // Here we now have an array of resolved API values
        // Map, flatten, reduce, etc.. to whatever we need 
        // in state for the CardList

        const reducedCards = allCardsResults.reduce((acc, cardResult) => acc.concat(cardResult), []);

        this.setState({
          cards: reducedCards,
        });
      })
      .catch(error => {
        // do any clean up or state management here should
        // any errors or promises get rejected
      });
  }        

  render () {
    const { cards } = this.state;
    return (
      <div className='ui container'>
        <SearchBar onSubmit={this.onSearchSubmit} />
        { cards && <CardList cards={cards} />} // Only render if `cards` is truthy
      </div>
    )
  }
}
export default App

Рабочий пример

const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];

new Promise((resolve, reject) => resolve(numbers))
.then(result => {
  console.log(`Initial numbers array: ${result}`);
  const promiseArray = result.map(key => {
    return Promise.resolve({ key, numbers });
  });
  return Promise.all(promiseArray);
})
.then(moreNumbers => {
  console.log(`More numbers: ${JSON.stringify(moreNumbers)}`);
  const reducedNumbers = moreNumbers.reduce((acc, mn) => acc.concat(mn.numbers), []);
  return Promise.resolve(reducedNumbers);
})
.then(finalNumberArray => console.log(`Final number array: ${finalNumberArray}`));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...