Как сопоставить ответ API JSON, содержащий массив объектов, с таблицей ag-grid - PullRequest
0 голосов
/ 07 мая 2020

Я хочу сопоставить ответ, который я получаю от API, с компонентом AgGridReact. Суть страницы заключается в том, чтобы пользователь мог ввести символ фондовой биржи, а затем, при желании, выбрать даты, чтобы найти цены на акции между двумя датами. Я могу нормально связаться с API. Я получаю такой же ответ, как здесь JSON Response . Ответ представляет собой массив, содержащий несколько объектов (в зависимости от поиска). Проблема заключается в том, чтобы взять ответ и сопоставить его с таблицей ag-grid-response.

Это код для заголовков таблиц

const columns = [
  { headerName: "Sybmol", field: "symbol" }, 
  { headerName: "Name", field: "name" }, 
  { headerName: "Open", field: "open" }, 
  { headerName: "High", field: "high" }, 
  { headerName: "Low", field: "low" }, 
  { headerName: "Close", field: "close" }, 
  { headerName: "Volumes", field: "volumes" }, 
  { headerName: "Time", field: "time" }, 
]

Первоначально я думал, что это будет работать как обычная функция карты:

useEffect(() => {
  fetch(url, { headers })
    .then(res => res.json())
    .then(data => data.stocks)
    .then(stocks =>
        stocks.map(stock => {
          return{
            sybmol: stock.symbol,
            name: stock.name,
            //etc...
          }
        }))
}, [search, FromDate, ToDate])

Однако это дает мне error Unhandled Rejection (TypeError): Невозможно прочесть свойство 'map' неопределенного

Вот JSON Запрошенные данные

   (17) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}]
0: {timestamp: "2020-03-23T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 10.9, …}
1: {timestamp: "2020-03-22T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 10.6526, …}
2: {timestamp: "2020-03-19T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 11.6, …}
3: {timestamp: "2020-03-18T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 14.24, …}
4: {timestamp: "2020-03-17T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 15.785, …}
5: {timestamp: "2020-03-16T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 12.4065, …}
6: {timestamp: "2020-03-15T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 15.3, …}
7: {timestamp: "2020-03-12T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 14.05, …}
8: {timestamp: "2020-03-11T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 16.31, …}
9: {timestamp: "2020-03-10T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 15.82, …}
10: {timestamp: "2020-03-09T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 14.87, …}
11: {timestamp: "2020-03-08T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 15.02, …}
12: {timestamp: "2020-03-05T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 17.54, …}
13: {timestamp: "2020-03-04T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 18.36, …}
14: {timestamp: "2020-03-03T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 19.66, …}
15: {timestamp: "2020-03-02T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 19.05, …}
16: {timestamp: "2020-03-01T14:00:00.000Z", symbol: "AAL", name: "American Airlines Group", industry: "Industrials", open: 19.8, …}
length: 17
__proto__: Array(0)

Код страницы (Не удалось включить информацию API, поскольку она является частной)

import React, { useState, useEffect, }from 'react';
import './Quote.css';
import { Button, Form, FormGroup } from 'reactstrap';
import SearchStocks from './SearchStocks';
import { AgGridReact } from "ag-grid-react";

function SearchBar(props){
  const [innerSearch, setInnerSearch] = useState('');

  return (
    <div>
      <label className="CheckStocks-SearchBar-Label" htmlFor="search">Search By Symbol:</label>
      <input className="CheckStocks-SearchBar" name="search" id="search" type="search" value={innerSearch} onChange={(e) => setInnerSearch(e.target.value)} />
      
      <Button className="CheckStocks-SearchBar-Button" color="primary" size="lg" id="search-button" type="button" 
              onClick={() => props.onSubmit(innerSearch)}>
        Search
      </Button>
    </div>
  );
}

function FromDateSelector(props){
  const [innerDate, setInnerDate] = useState('');
  

  return(
    <div>
      <input type="date" value={innerDate} onChange={(e) => setInnerDate(e.target.value)} />
      <button onClick={() => props.onSubmit(innerDate)}>Select From Date</button>
    </div>
  )
}

function ToDateSelector(props){
  const [innerDate2, setInnerDate2] = useState('');
  

  return(
    <div>
      <input type="date" value={innerDate2} onChange={(e) => setInnerDate2(e.target.value)} />
      <button onClick={() => props.onSubmit(innerDate2)}>Select To Date Date</button>
    </div>
  );
}


function GetStocks(search, FromDate, ToDate) {
  

  const [ rowData, setRowData ] = useState([]);
  

  let token = localStorage.getItem("token");
  const headers = {
    accept: "application/json",
    "Content-Type": "application/json",
    Authorization: `Bearer` + //Usually a token as well
  }
  
  let FromDateLink = '?from=' + FromDate
  const url = 'TheAPiUrl' + search + FromDateLink;

  function ApiCall(){
    fetch(url, { headers })
    .then((res) => res.json())
  }

useEffect(() => {
  fetch(url, { headers })
    .then(res => res.json())
    .then(data => data.stocks)
    .then(stocks =>
        stocks.map(stock => {
          return{
            sybmol: stock.symbol,
            name: stock.name,
            //etc...
          }
        }))
}, [search, FromDate, ToDate])

  return{
    rowData,
  }
  
}


function Quote() {
  
  const [search, setSearch] = useState('');
  const [FromDate, setFromDate] = useState('');
  const [ToDate, setToDate] = useState('');
  const { rowData } = GetStocks(search, FromDate, ToDate);
  

  return(
    <div>
      <h1 className="Quote-Title">Quote Page</h1>
      <div className="Quote-Search-Box">
        <SearchBar onSubmit={setSearch} />
        <FromDateSelector onSubmit={setFromDate} />
        <ToDateSelector onSubmit={setToDate} />
        <h1>{search}</h1>
        <br></br>
        <h1>{FromDate}</h1>
        <h1>{ToDate}</h1>
        
        
      </div>
    </div>
  )
}


export default Quote;

Мой первый вопрос о переполнении стека. Спасибо за вашу помощь.

1 Ответ

1 голос
/ 07 мая 2020

Вы должны сохранить возвращенный ответ от запроса API в состоянии вашего компонента.

const [ data, setData ] = useState([]);

А в вашем методе GetStocks вам нужно будет обновить состояние после того, как ответ будет возвращен:

useEffect(() => {
  fetch(url, { headers })
    .then(res => res.json())
    .then(data => data.stocks)
    .then(stocks =>
      const res = stocks.map(stock => ({
        sybmol: stock.symbol,
        name: stock.name,
        //etc...
      }));
      setData(res);
    );
}, [search, FromDate, ToDate]);

Наконец, на самом рендеринге AgGridReact вам нужно будет передать данные в свойства rowData:

<AgGridReact
  rowData={data}>
  // other props such as columnDefs
</AgGridReact>
...