0

The strings that I want to printed in the console earlier than the json data. I am now working with the food data central API


const fetch = require("node-fetch");

const params = {
    api_key: '<api_key>',
    query: 'chicken breast raw',
    dataType: ["Survey (FNDDS)"],
    pagesize: 5,
}

const api_url = `https://api.nal.usda.gov/fdc/v1/foods/search?api_key=${encodeURIComponent(params.api_key)}&query=${encodeURIComponent(params.query)}&dataType=${encodeURIComponent(params.dataType)}&pageSize=${encodeURIComponent(params.pagesize)}`

function getData(){
    return fetch(api_url).then(response => response.json())
}

console.log("Protein:")
getData().then(data=> console.log(data.foods[0].foodNutrients[0].value))

console.log("Fats:")
getData().then(data=> console.log(data.foods[0].foodNutrients[1].value))

console.log("Carbs:")
getData().then(data=> console.log(data.foods[0].foodNutrients[2].value))

Output: Protein: Fats: Carbs: 8.8 0 26.2

I just want to print first the string "protein" after the protein value from the json and so on

Andy
  • 61,948
  • 13
  • 68
  • 95

2 Answers2

1

You are using Promises, which are asynchronously-executing code. This means that things might not necessarily execute in the laid-out order. For example, fetch makes a web request and then immediately executes any following code, only executing then once data has been returned from the external host.

You could add the logging inside the promise callback (instead of outside as you currently have it)

getData().then(data=> {
    console.log("Protein: ");
    console.log(data.foods[0].foodNutrients[0].value);
})

getData().then(data=> {
    console.log("Fats: ");
    console.log(data.foods[0].foodNutrients[1].value);
});

getData().then(data=> {
    console.log("Carbs: ");
    console.log(data.foods[0].foodNutrients[2].value);
});

However, in this situation, I think it's even simpler than that. Every time we call getData() it makes a new request even though we're loading the same data, so it may make sense to do the request once and then log everything?

getData().then(data => {
    const foods = data.foods[0];
    console.log("Protein: ");
    console.log(foods.foodNutrients[0].value);

    console.log("Fats: ");
    console.log(foods.foodNutrients[1].value);

    console.log("Carbs: ");
    console.log(foods.foodNutrients[2].value);
});

Or, using a map to make adding new food groups a little easier?

const foods = {
  0: 'Protein',
  1: 'Fats',
  2: 'Carbs'
};

getData().then(data => {
  Object.keys(foods).forEach(key => {
    console.log(`${foods[key]}: `);
    console.log(data.foods[0].foodNutrients[key].value);
  });
});
Luke
  • 1,060
  • 8
  • 19
  • I implement your answer my friend but know I know get any data from the API. Instead I get an time out error: FetchError: request to failed, reason: connect ETIMEDOUT 2600:1f12:18a:7d00:217:68d:2c2:3718:443 – Florian Dima Feb 12 '23 at 15:23
  • @FlorianDima that sounds like there is an issue with the URL you are specifying for your `fetch` command (well, either that or your network connection). If you type the URL out into the browser are you able to access the site normally? – Luke Feb 13 '23 at 19:14
0

Have you tried to use await? e.g.

function getData(){
    return fetch(api_url).then(response => response.json())
}

console.log("Protein:")
await getData().then(data=> console.log(data.foods[0].foodNutrients[0].value))

console.log("Fats:")
await getData().then(data=> console.log(data.foods[0].foodNutrients[1].value))

console.log("Carbs:")
await getData().then(data=> console.log(data.foods[0].foodNutrients[2].value))
Roshaan
  • 11
  • 3
  • I get an error : SyntaxError: await is only valid in async functions and the top level bodies of modules – Florian Dima Feb 12 '23 at 13:55
  • Node has had top-level await since v14.8, and `fetch` since v18 (so you don't necessarily need `node-fetch` either. – Andy Feb 12 '23 at 14:30
  • You mention await but don't use await at all. Is this an error? @Roshann – Robert Feb 12 '23 at 14:36