简体   繁体   中英

How to get API data from node js to display on React

I'm learning react and node js and I'm making a macro calculator website and basically I get data (calories, macro ratio, etc..) from the user on client side then using those data I make a get request to edamam API server to get (foodID, uri, unit) and post those data again to get macros for each food. Then I calculated data. (It's working fine up to this point on the backend). And I want send this data to back to frontend to display and it's not working here. I'm using axios for the requests. I'm also not too sure it's right way to make API calls. Any help would be appreciated Thank you

Send data to backend from 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 to make API calls and process data

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); }
});

Use the data to display on 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

Error message

chrome控制台错误信息

-----------------------Edit-------------------------------------------

Instead of res.json(data) I added below

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

display on react

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>
  )
}

I still get an error

在此处输入图像描述

Your error is generated because you are asking to a GET method that doesn't exist on backend, that's why you see 404 there. You actually have a POST declared (getData), you should request to the POST method by passing the values on the body. something like this:

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

Axios is fine, if you don't want to use an external package you can use fetch. You can find the documentation here .

For the render: you have to do something different, since you are receiving an object you should map on keys, change this:

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

to something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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