Home > Enterprise >  How to get API data from node js to display on React
How to get API data from node js to display on React

Time:07-28

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 console error message

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

enter image description here

CodePudding user response:

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>
  • Related