I'm pretty new to JS and very very new to Node. I'm trying to make a very simple app that pulls JSON data from the edamam API (https://rapidapi.com/edamam/api/edamam-nutrition-analysis). I've got the API working, and I now want to use the data that the request returns, but it's stuck inside a callback function and I can't figure out how to access it outside of the function that retrieves it.
From what I can tell, it's something to do with the async nature of Node. I've tried re-ordering it in every way I can think of (for over 6 hours!), but all I ever get is undefined variables. I'm figuring that's because they haven't been set yet, but I don't quite have enough of a handle on callback functions to understand how to fix this.
Eventually I want to be able to use the JSON data to update the contents of HTML elements.
const unirest = require('unirest');
var getNutritionInfo = {
mkString: function(foodStr){
var ingredients = new Array();
ingredients.push(foodStr);
console.log(foodStr)
params = {
ingr: ingredients,
};
esc = encodeURIComponent;
query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
foodQuery = query.replace(/%20/g,"+");
return(foodQuery);
},
analyse: function(foodStr){
var cals;
url = "https://edamam-edamam-nutrition-analysis.p.rapidapi.com/api/nutrition-data"
searchQuery = getNutritionInfo.mkString(foodStr);
function requestData(callback){
unirest.get(url+"?" + searchQuery)
.header("X-RapidAPI-Key", "c5c219c7b0mshbf5b602f68caddep1cd8cfjsn01a1be1f45a4")
.end(function (result) {
cals = result.body.totalNutrients.ENERC_KCAL.quantity;
console.log(cals + " first");
callback();
});
}
requestData(function(){
console.log(cals + " second");
getNutritionInfo.getData();
});
},
getData: function(){
var calories = getNutritionInfo.analyse.cals;
console.log(calories + " third");
return calories;
}
};
the final console.log is ALWAYS undefined, whereas I am wanting it to return the value on line of cals (result.body.totalNutrients.ENERC_KCAL.quantity);
Also, I'm very sorry. I'm aware that there must be cleaner ways to organise functions and format code. I'll get there eventually :)
the final console.log is ALWAYS undefined, whereas I am wanting it to return the value on line of cals (result.body.totalNutrients.ENERC_KCAL.quantity);
This is because of the asynchronous nature of the nodejs. To get value from requestData()
, you need to pass cal
as a value to the callback.
Making those changes,
'use strict';
const unirest = require('unirest');
var getNutritionInfo = {
mkString: function (foodStr) {
var ingredients = new Array();
ingredients.push(foodStr);
console.log(foodStr)
params = {
ingr: ingredients,
};
esc = encodeURIComponent;
query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
foodQuery = query.replace(/%20/g, "+");
return (foodQuery);
},
analyse: function (foodStr) {
url = "https://edamam-edamam-nutrition-analysis.p.rapidapi.com/api/nutrition-data"
searchQuery = getNutritionInfo.mkString(foodStr);
function requestData(callback) {
unirest.get(url + "?" + searchQuery)
.header("X-RapidAPI-Key", "c5c219c7b0mshbf5b602f68caddep1cd8cfjsn01a1be1f45a4")
.end(function (result) {
let cals = result.body.totalNutrients.ENERC_KCAL.quantity;
console.log(cals + " first");
callback(cals); // pass value here
});
}
requestData(function (cals) { // get value after completion
console.log(cals + " second");
getNutritionInfo.getData();
});
},
getData: function () {
var calories = getNutritionInfo.analyse.cals;
console.log(calories + " third");
return calories;
}
};