繁体   English   中英

如何从节点 js 获取 API 数据以在 React 上显示

[英]How to get API data from node js to display on React

我正在学习 react 和 node js,我正在制作一个宏计算器网站,基本上我从客户端的用户那里获取数据(卡路里、宏比率等),然后使用这些数据向 edamam API 发出获取请求服务器获取(foodID,uri,unit)并再次发布这些数据以获取每种食物的宏。 然后我计算了数据。 (到目前为止,它在后端工作正常)。 我想将此数据发送回前端以显示,但它在这里不起作用。 我正在使用 axios 来处理请求。 我也不太确定进行 API 调用的正确方法。 任何帮助将不胜感激谢谢

从 React 向后端发送数据

async function postData(e){
    e.preventDefault();

    try{
      await axios.post("http://localhost:4000/getData", {formData})
    }
    catch(error){
      console.log(error.response.data);
    }
  }

Node.js 进行 API 调用和处理数据

app.post("/getData", (req, res) =>{
  // data from React
  const targetKcal = req.body.formData.calories;
  const proteinRatio = req.body.formData.proteinRatio;
  const fatRatio = req.body.formData.fatRatio;
  const carbRatio = req.body.formData.carbRatio;
  const proteinSource = req.body.formData.proteinSource;
  const fatSource = req.body.formData.fatSource;
  const carbSource = req.body.formData.carbSource;
  const getURL = "https://api.edamam.com/api/food-database/v2/parser?";
  const postURL = "https://api.edamam.com/api/food-database/v2/nutrients?";
  //GET Request to parse and get uri and foodID to post
  try{
    Promise.all([
      axios.get(getURL, {params :{"ingr" : proteinSource}}),
      axios.get(getURL, {params :{"ingr" : fatSource}}),
      axios.get(getURL, {params :{"ingr" : carbSource}}),
  
  ]).then(axios.spread((proteinData, fatData, carbData) => { 
    try{
     //post data to get macro info for each macros
    Promise.all([
      axios.post(postURL, {"ingredients" :[{"quantity":1, "measureURI": proteinData.data.hints[0].measures.filter(obj => obj["label"] === "Gram")[0].uri,"foodId":proteinData.data.parsed[0].food.foodId}]}),
 
      axios.post(postURL, {"ingredients" :[{"quantity":1, "measureURI": fatData.data.hints[0].measures.filter(obj => obj["label"] === "Gram")[0].uri,"foodId":fatData.data.parsed[0].food.foodId}]}),
  
      axios.post(postURL, {"ingredients" :[{"quantity":1, "measureURI": carbData.data.hints[0].measures.filter(obj => obj["label"] === "Gram")[0].uri,"foodId":carbData.data.parsed[0].food.foodId}]})
    
     ]).then(axios.spread((data1, data2, data3) => {

          let proteinKcal = data1.data.totalNutrients.ENERC_KCAL.quantity;
          let protein = data1.data.totalNutrients.PROCNT.quantity;
          let proteinFat = data1.data.totalNutrients.FAT.quantity;
          let proteinCarb = data1.data.totalNutrients.CHOCDF.quantity;

          let fatKcal = data2.data.totalNutrients.ENERC_KCAL.quantity;
          let fatProtein = data2.data.totalNutrients.PROCNT.quantity;
          let fat = data2.data.totalNutrients.FAT.quantity;
          let fatCarb = data2.data.totalNutrients.CHOCDF.quantity;


          let carbKcal = data3.data.totalNutrients.ENERC_KCAL.quantity;
          let carbProtein = data3.data.totalNutrients.PROCNT.quantity;
          let carbFat = data3.data.totalNutrients.FAT.quantity;
          let carb = data3.data.totalNutrients.CHOCDF.quantity;

          //Calculate each macros for target calories 
          const proteinTargetGram = (targetKcal * (proteinRatio / 100))/proteinKcal;
          const fatTargetGram = (targetKcal * (fatRatio / 100))/fatKcal;
          const carbTargetGram = (targetKcal * (carbRatio / 100))/carbKcal;
          
          proteinKcal *= proteinTargetGram;
          protein *= proteinTargetGram;
          proteinFat *= proteinTargetGram;
          proteinCarb *= proteinTargetGram;
          
          fatKcal *= fatTargetGram;
          fatProtein *= proteinTargetGram;
          fat *= fatTargetGram;
          fatCarb *= proteinTargetGram; 

          carbKcal *=carbTargetGram;  
          carbProtein *= proteinTargetGram;
          carbFat *= proteinTargetGram;
          carb *= carbTargetGram;

          const totalKcal = (proteinKcal + fatKcal + carbKcal).toFixed(0);
          const totalProtein = (protein + fatProtein + carbProtein).toFixed(0);
          const totalFat = (proteinFat + fat + carbFat).toFixed(0);
          const totalCarb = (proteinCarb + fatCarb + carb).toFixed(0);

          const data = {
            "totalKcal": totalKcal, 
            "totalProtein": totalProtein,
             "totalFat": totalFat,
             "totalCarb": totalCarb, 
             "proteinTargetGram": proteinTargetGram,
             "fatTargetGram": fatTargetGram,
             "carbTargetGram":carbTargetGram
            };
        
          //send back the data
          res.json(data);
          
    }))
    }catch(err) { console.log(err); }
  }));
  }
  catch (err) { console.error(err); }
});

使用数据在 React 上显示

function Result() {
  const [data, setData] = useState([]);
  
  useEffect(()=>{
    const getData = async ()=> {
      const response = await axios.get('/getData');
      setData(response.data);
    };
    getData();
  });
  

  return (
    <div>
      <h1>{data.map(item => item)}</h1>
    </div>
  )
}

export default Result

错误信息

chrome控制台错误信息

- - - - - - - - - - - -编辑 - - - - - - - - - - - - - -----------------

我在下面添加了 res.json(data) 而不是 res.json(data)

axios.post('/getData', data)
.then(res => console.log(res.json))
.catch(err => console.log(err.json));

反应时显示

function Result() {
  const [data, setData] = useState([]);
  
  useEffect(()=>{
    const getData = async ()=> {
      const response = await axios.get('http://localhost:4000/getData');
      setData(response.data);
    };
    
    getData();
  });
  

  return (
    <div>
      <h1>{Object.keys(data).map(key => data[key])}</h1>
    </div>
  )
}

我仍然收到错误

在此处输入图像描述

生成错误是因为您要求后端不存在的 GET 方法,这就是您在那里看到 404 的原因。 您实际上有一个 POST 声明(getData),您应该通过在主体上传递值来请求 POST 方法。 像这样的东西:

axios.post('/getData', {
// pass the formData here
  formData:{ 
      // calories: ...,
      // ...
  }
})
.then(function (response) {
    // update state
})
.catch(function (error) {
    // handle error
});

Axios 很好,如果您不想使用外部 package 可以使用 fetch。 您可以在此处找到文档。

对于渲染:你必须做一些不同的事情,因为你收到一个 object 你应该在键上 map ,改变这个:

<h1>{data.map(item => item)}</h1>

像这样:

<h1>{Object.keys(data).map(key => key + ": " + data[key])}</h1>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM