Как вызвать весь массив в вызове API

#javascript #reactjs

#javascript #reactjs

Вопрос:

У меня есть скрипт, который вызывает API из React.

У меня есть массив символов const assets = ['ADA','KAVA','DOGE'];

Моя строка API выглядит следующим образом

https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}amp;tsyms=USDamp;api_key=API-KEY-HERE

Как вы можете видеть, я вызываю API 3 раза для каждого символа, например, если я запущу этот код, он будет выполняться 3 раза

 https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADAamp;tsyms=USDamp;api_key=API-KEY-HERE
https://min-api.cryptocompare.com/data/pricemulti?fsyms=KAVAamp;tsyms=USDamp;api_key=API-KEY-HERE
https://min-api.cryptocompare.com/data/pricemulti?fsyms=DOGEamp;tsyms=USDamp;api_key=API-KEY-HERE
  

Как я могу вызвать API, чтобы использовать весь массив при вызове API. Предполагается, что в конце строки это будет так

https://min-api.cryptocompare.com/data/pricemulti?fsyms=ADA,KAVA,DOGEamp;tsyms=USDamp;api_key=API-KEY-HERE ;

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

Вот мой полный код:

 import React, { useState, useEffect} from "react";
import axios from "axios";
require('dotenv').config()

const assets = ['ADA','KAVA','DOGE'];

export default function App() {
  const [queries, setQueries] = useState(
    JSON.parse(localStorage.getItem("queries")) || []
  );
  const [symbol, setSymbol] = useState("");
  const [price, setPrice] = useState("");
  const [dropdown, setDropdown] = useState([]);
  const [dataApi, setDataApi] = useState([]);
  const [filtered, setFiltered] = useState([]);

  useEffect(() => {
    setTimeout(() => {
      getApiData();
    }, 1000 * 60);
    if (dataApi.length > 0) {
      const clientQueriesNames = queries.map(rec => rec.symbol);
      const newFilteredArray = dataApi.filter(apiQuery => {
        if (clientQueriesNames.includes(apiQuery.Symbol)) {
          return apiQuery.Open >
            queries.find(rec => rec.symbol === apiQuery.Symbol).price
            ? apiQuery
            : false;
        }
      });
      const newQueries = queries.filter(rec => {
        return typeof newFilteredArray.find(
          query => query.Symbol === rec.symbol
        ) === "undefined"
          ? rec
          : false;
      });
      setFiltered(newFilteredArray);
      setQueries(newQueries);
      localStorage.setItem("queries", JSON.stringify(newQueries));
      newFilteredArray.forEach(query => {
        window.Email.send({
          Host: "smtp.gmail.com",
          Username: process.env.REACT_APP_DB_USER,
          Password: process.env.REACT_APP_DB_PASS,
          To: process.env.REACT_APP_DB_RECEIVER,
          From: process.env.REACT_APP_DB_USER,
          Subject: `${query.Symbol} is up`,
          Body: `${query.Symbol} is UP`
      });
      console.log(newFilteredArray);
    }
  }, [dataApi]);

  const getApiData = () => {
    const getString = symbol =>
      `https://min-api.cryptocompare.com/data/pricemulti?fsyms=${symbol}amp;tsyms=USDamp;api_key=API-KEY-HERE`;

    function getAxious(id) {
      const url = getString(id);
      return axios.get(url);
    }

    const BUCKET_SIZE = 150;
    const bucketArray = assets.reduce(
      (arr, rec) => {
        if (arr[arr.length - 1].length < BUCKET_SIZE) {
          arr[arr.length - 1] = [...arr[arr.length - 1], rec];
          return arr;
        }
        return [...arr, [rec]];
      },
      [[]]
    );

    bucketArray
      .reduce((acc, rec) => {
        return acc.then(results => {
          return Promise.all(
            rec.map(item =>
              getAxious(item).then(({ data }) => {
                return {
                  Symbol: item,
                  Open: data
                };        
              })
            )
          ).then(x => {
            return [...x, ...results];
          });
        });
      }, 
      Promise.resolve([]))
      .then(res => {
        setDataApi(res);
      });
  };

  const onChangeSymbol = e => {
    setSymbol(e.target.value);
  };

  const onChangePrice = e => {
    setPrice(e.target.value);
  };

  var today = new Date();
  var date =
    today.getFullYear()   "-"   (today.getMonth()   1)   "-"   today.getDate();
  var time =
    today.getHours()   ":"   today.getMinutes()   ":"   today.getSeconds();
  var dateTime = date   " "   time;

  const onClick = () => {
    if (symbol !== "" amp;amp; price !== "") {
      setQueries(queries => {
        const query = {
          symbol,
          price,
          dateTime
        };
        localStorage.setItem("queries", JSON.stringify([...queries, query]));
        return [...queries, query];
      });
      setSymbol("");
      setPrice("");
    }
  };
  useEffect(() => {
    if (symbol !== "" amp;amp; symbol !== assets.find(rec => rec === symbol)) {
      setDropdown(assets.filter(rec => rec.indexOf(symbol) > -1));
    } else {
      setDropdown([]);
    }
  }, [symbol]);
  return (
    <div id="DropDownArea" className="DropDownField">
      <div id="PriceAlertHistory">
        <h6>Price Alert History</h6>
      </div>
      <ul>
        {queries.map(query => (
          <li key={query.symbol}>
            {`${query.symbol}`  
              " "  
              `${query.price}`  
              " "  
              "("  
              query.dateTime  
              ")"}
            <button
              onClick={() => {
                const newQueries = queries.filter(
                  rec => rec.symbol !== query.symbol
                );
                setQueries(newQueries);
                localStorage.setItem("queries", JSON.stringify(newQueries));
              }}
            >
              X
            </button>
          </li>
        ))}
      </ul>
      <input
        type="text"
        placeholder="Symbol"
        value={symbol}
        onChange={onChangeSymbol}
      />
      <input
        type="number"
        placeholder="Price"
        value={price}
        onChange={onChangePrice}
      />
      <button type="submit" onClick={onClick}>
        Set
      </button>
      <ul>
        {dropdown.length !== 0
          ? dropdown.map(asset => {
              return (
                <li
                  onClick={() => {
                    setSymbol(asset);
                    setDropdown([]);
                  }}
                >
                  {asset}
                </li>
              );
            })
          : false}
      </ul>
    </div>
  );
}
  

Комментарии:

1. process.env.REACT_APP_DB_PASS на стороне клиента? eek

Ответ №1:

Вы можете использовать функцию объединения массива следующим образом

 const assets = ['ADA','KAVA','DOGE'];
assets.join(",");
  

Результат будет

 ADA,KAVA,DOGE
  

Если ваш API не позволяет этого, попробуйте использовать подобные обещания.

 let promises = [];
array.map(item => promises.push(<YOUR URL>));
Promise.All(promises).then(responses => {
  //YOUR RESPONSES OF APIS IN THE EXACT SEQUENCE AS THEY ARE PUSHED
}).catch(error => {
  //YOUR ERROR HANDLING
});
  

Комментарии:

1. Привет! Спасибо за ответ, к сожалению, он по-прежнему вызывает 3 вызова API вместо одного.