Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 同时处理两个API_Javascript_Reactjs_Api_Fetch - Fatal编程技术网

Javascript 同时处理两个API

Javascript 同时处理两个API,javascript,reactjs,api,fetch,Javascript,Reactjs,Api,Fetch,我想使用React从API加载planet数据,并将这些数据放入Material UI卡组件中。不幸的是,我使用的planet API没有照片,我也想在卡片中显示这些照片。为此,我使用了另一个API 获取行星数据的API: 获取行星图像的API: 我已经知道如何将每个行星组件及其各自的信息渲染到一张卡片中,但不知道如何将每个NASA图像映射到各自的行星: 这是App.js组件的代码: import React, {useState, useEffect} from 'react'; import

我想使用React从API加载planet数据,并将这些数据放入Material UI卡组件中。不幸的是,我使用的planet API没有照片,我也想在卡片中显示这些照片。为此,我使用了另一个API

获取行星数据的API:
获取行星图像的API:

我已经知道如何将每个行星组件及其各自的信息渲染到一张卡片中,但不知道如何将每个NASA图像映射到各自的行星:

这是App.js组件的代码:

import React, {useState, useEffect} from 'react';
import './App.css';
import axios from 'axios'
import Block from "./Block"


function App() {
  const [planets, setPlanets] = useState([])
  const [images, setImages] =useState([])
 
  const getPlanets = async()=>{
    const data = await fetch
    ('https://api.le-systeme-solaire.net/rest/bodies') //Await for first fetch promise to resolve
    const planets = await(data.json()) //Await for data.json to resolve and save this planets

    setPlanets(planets.bodies.filter 
        (planet =>planet.isPlanet && planet.name.indexOf('1')===-1)) 
  }

  const getImages = (name)=>{
    axios.get('https://images-api.nasa.gov/search',{
      params:{
        q: name
      }
    })
    .then(res => 
      setImages(images.concat(res.data.collection.items[0].links[0].href)))
  } 

  console.log(planets)   

  useEffect(()=>{
    getPlanets();
  },[])
  
  useEffect(()=>{
    if(planets){
      planets.map(planet =>getImages(planet.englishName))
    }
  },[])

 console.log(images)
 console.log(planets.length)

  return (
    <div className="App">
      {planets.map(planet => 
        (<Block 
          key = {planet.id}
          id = {planet.id}
          name = {planet.englishName}
          dateDiscovered = {planet.discoveryDate}
          mass = {planet.mass.massValue}
          massExp = {planet.mass.massExponent}
          image = ???
        />)
      )}
    </div>
  );
}

export default App;
import React,{useState,useffect}来自“React”;
导入“/App.css”;
从“axios”导入axios
从“/Block”导入块
函数App(){
常数[行星,集合行星]=useState([])
常量[images,setImages]=useState([])
常量getPlanets=async()=>{
const data=等待获取
('https://api.le-systeme-solaire.net/rest/bodies“)//等待第一次获取承诺的解决
const planets=await(data.json())//等待data.json解析并保存此行星
设置行星(行星。天体。过滤器)
(planet=>planet.isPlanet&&planet.name.indexOf('1')=-1))
}
常量getImages=(名称)=>{
axios.get()https://images-api.nasa.gov/search',{
参数:{
问:姓名
}
})
。然后(res=>
setImages(images.concat(res.data.collection.items[0].links[0].href)))
} 
控制台日志(行星)
useffect(()=>{
获取行星();
},[])
useffect(()=>{
if(行星){
planet.map(planet=>getImages(planet.englishName))
}
},[])
console.log(图像)
控制台.日志(行星.长度)
返回(
{行星。地图(行星=>
()
)}
);
}
导出默认应用程序;
Block.js的代码如下:

import React, {useState, useEffect} from 'react'
import './Block.css'

import {Card, CardContent} from '@material-ui/core'
function Block(props){
    return (
        <div>
            <Card>
                <CardContent>
                    <div className = "planetInfo">
                        <h4>{props.name}</h4>
                        <h5>Mass: {props.mass}*10^{props.massExp} kg</h5>
                        <h5>Discovery Date: {props.dateDiscovered}</h5>
                        <h5>ID: {props.id}</h5>
                        <img src = {props.image}/>
                    </div>
                </CardContent>
            </Card>
        </div>
    )
}


export default Block
import React,{useState,useffect}来自“React”
导入“./Block.css”
从“@material ui/core”导入{Card,CardContent}
功能块(道具){
返回(
{props.name}
质量:{props.Mass}*10^{props.massExp}千克
发现日期:{props.dateDiscovered}
ID:{props.ID}
)
}
导出默认块

我感觉我的结构不对。如果有任何帮助,我们将不胜感激。

您可以根据行星的阵列索引轻松地绘制行星和图像,前提是:

你按顺序取回它们

因为有8颗行星,所以会有8张图像;因此,您的
Array.map
函数如下所示:

 {planets.map((planet,index) => 
  (<Block 
  key = {planet.id}
  id = {planet.id}
  name = {planet.englishName}
  dateDiscovered = {planet.discoveryDate}
  mass = {planet.mass.massValue}
  massExp = {planet.mass.massExponent}
  image = images[index]
  
  />))}
{行星地图((行星,索引)=>
())}

您可以
使用effect
并且当行星数组发生变化时,您可以迭代行星数组中行星的名称并调用图像API

React.useEffect(() => {
  async function fetchAllImages() {
    const allImages = [];

    for await (const planet of planets) {
      const { data }  = axios.get('https://images-api.nasa.gov/search',{
      params:{
        q: planet.name
      }})

      allImages.push(data);
    }

    setImages(allImages);
  }

  fetchAllImages();
}, [planets])

同时处理多个API调用是一个非常困难的问题。我不知道这是否有效,但你为什么不改变呢
const[images,setImages]=useState([])
to
const[images,setImages]=useState({})


  axios.get('https://images-api.nasa.gov/search',{
 
 params:{
  q: name

 }})
 .then(res => setImages(images.concat(res.data.collection.items[0].links[0].href)))
} 


然后,您可以使用
planets
数组循环,根据植物名称从
图像
对象中拾取URL。

我建议将两个数据获取合并到一个单一的效果挂钩回调中。首先获取并过滤天体列表中的真实行星,然后获取图像并将行星和图像映射到单个行星数据数组中。现在只需将
image={planet.image}
传递到
Block

function App() {
  const [planets, setPlanets] = useState([]);

  const getPlanets = async () => {
    const data = await fetch("https://api.le-systeme-solaire.net/rest/bodies"); //Await for first fetch promise to resolve
    const planets = await data.json(); //Await for data.json to resolve and save this planets

    // filter planet data
    const filteredPlanets = planets.bodies.filter(
      (planet) => planet.isPlanet && planet.name.indexOf("1") === -1
    );

    // define function here to avoid needing it as dependency
    // return GET request response image value
    const getImages = (name) => {
      return axios
        .get("https://images-api.nasa.gov/search", {
          params: {
            q: name
          }
        })
        .then((res) => res.data.collection.items[0].links[0].href);
    };

    // Fetch and await all images
    const planetImages = await Promise.all(
      filteredPlanets.map((planet) => getImages(planet.englishName))
    );

    // Merge planets and images arrays
    const planetsWithImages = filteredPlanets.map((planet, i) => ({
      ...planet,
      image: planetImages[i]
    }));

    setPlanets(planetsWithImages);
  };

  useEffect(() => {
    getPlanets();
  }, []);

  return (
    <div className="App">
      {planets.map((planet) => (
        <Block
          key={planet.id}
          id={planet.id}
          name={planet.englishName}
          dateDiscovered={planet.discoveryDate}
          mass={planet.mass.massValue}
          massExp={planet.mass.massExponent}
          image={planet.image} // <-- pass planet.image
        />
      ))}
    </div>
  );
}
函数应用程序(){
常数[行星,集合行星]=useState([]);
常量getPlanets=async()=>{
常量数据=等待获取(“https://api.le-systeme-solaire.net/rest/bodies“”;//等待第一次获取承诺解决
const planets=wait data.json();//wait for data.json解析并保存此行星
//筛选行星数据
const filteredPlanets=planets.bodies.filter(
(planet)=>planet.isPlanet&&planet.name.indexOf(“1”)=-1
);
//在此处定义函数以避免将其作为依赖项
//返回GET请求响应映像值
常量getImages=(名称)=>{
返回轴
.get(“https://images-api.nasa.gov/search", {
参数:{
问:姓名
}
})
.then((res)=>res.data.collection.items[0]。链接[0]。href);
};
//获取并等待所有图像
const planetImages=等待承诺(
filteredPlanets.map((planet)=>getImages(planet.englishName))
);
//合并行星和图像阵列
const planetsWithImages=filteredPlanets.map((行星,i)=>({
…地球,
图像:平面图像[i]
}));
设置行星(有图像的行星);
};
useffect(()=>{
获取行星();
}, []);
返回(
{行星地图((行星)=>(

我会将图像添加到行星阵列中,然后完全删除图像阵列

在这些方面

    if(planets){
     planets.map(planet =>getImages(planet.englishName))
    }
   
  },[])
您的
getImages
函数正在获取图像并将其存储在
images

但是,由于您已经在绘制行星地图以获取行星名称,因此不要将这些图像存储在单独的变量中,而是将它们返回/存储在行星数组中

也许是这样的

if(planets){
    planets.map(planet => {
      const image = getImages(planet.englishName)
      return {...planet, image}
    })
  },[])
const getPlanets = async() => {
  const response = await fetch('https://api.le-systeme-solaire.net/rest/bodies')
  const data = await data.json()
  const planets = data.bodies.filter(planet =>planet.isPlanet && planet.name.indexOf('1') === -1)
    
  return planets
}      
 
const getImages = async (name) => {
  const response = await axios.get('https://images-api.nasa.gov/search', {params:{q: name}})
  const images = response.concat(res.data.collection.items[0].links[0].href)

  return images
}


useEffect(()=>{
      getPlanets()
        .then(planets => Promise.all(planets.map(async (planet) => {
          const image = await getImages(planet.englishName)
          return  {...planet, image }
        })))
        .then(planets => setPlanets(planets))
  },[])
现在这一行是
image=planet.image

也许可以用一个
useffect
这样的东西来完成这一切

if(planets){
    planets.map(planet => {
      const image = getImages(planet.englishName)
      return {...planet, image}
    })
  },[])
const getPlanets = async() => {
  const response = await fetch('https://api.le-systeme-solaire.net/rest/bodies')
  const data = await data.json()
  const planets = data.bodies.filter(planet =>planet.isPlanet && planet.name.indexOf('1') === -1)
    
  return planets
}      
 
const getImages = async (name) => {
  const response = await axios.get('https://images-api.nasa.gov/search', {params:{q: name}})
  const images = response.concat(res.data.collection.items[0].links[0].href)

  return images
}


useEffect(()=>{
      getPlanets()
        .then(planets => Promise.all(planets.map(async (planet) => {
          const image = await getImages(planet.englishName)
          return  {...planet, image }
        })))
        .then(planets => setPlanets(planets))
  },[])
*注意,我没有测试上述代码,但希望接近您需要的代码。

import React,{useState,useffect}来自'React';
import React, {useState, useEffect} from 'react';
import './App.css';
import axios from 'axios'
import Block from "./Block"


function App() {
  const [planets, setPlanets] = useState([])
  const [images, setImages] =useState([])
 

  const getPlanets = async()=>{
    const data = await fetch
    ('https://api.le-systeme-solaire.net/rest/bodies') //Await for first fetch promise to resolve
    const planets = await(data.json()) //Await for data.json to resolve and save this planets

    setPlanets(planets.bodies.filter 
        (planet =>planet.isPlanet && planet.name.indexOf('1')===-1)) 
    }      
 

  useEffect(()=>{
      getPlanets();
  },[])
  

  useEffect(() => {
    async function fetchAllImages() {
      const allImages = [];
  
      for await (const planet of planets) {
        const data  = await axios.get('https://images-api.nasa.gov/search',{
        params:{
          q: planet.englishName
        }})
        const res = await data.data.collection.items[0].links[0].href
        allImages.push(res);
      }
  
      setImages(allImages);
     

    }
  
    fetchAllImages();
  }, [planets])
  console.log(images)

  return (
    
   <div className="App">
     
 {planets.map((planet,index) => 
  (<Block 
  key = {planet.id}
  id = {planet.id}
  name = {planet.englishName}
  dateDiscovered = {planet.discoveryDate}
  mass = {planet.mass.massValue}
  massExp = {planet.mass.massExponent}
  image = {images[index]}
  
  />))}
  
   </div>
   
  );

}
export default App;
导入“/App.css”; 从“axios”导入axios 从“/Block”导入块 函数App(){ 常数[行星,集合行星]=useState([]) 常量[images,setImages]=useState([]) 常量getPlanets=async()=>{ const data=等待获取 ('https://api.le-systeme-solaire.net/rest/bodies“)//等待第一次获取承诺的解决