Insert dynamic id into api request link to display data - javascript

I have a problem with my code, can't find a solution to insert the id of the recipes that I have into a new request to display the calories of the recipes into HTML. All I want is to somehow add a dynamic id instead of the static 634091 id over there into the API url, because if I send that request and refresh my page it will not display the calories in HTML because it will be another id generated from every refresh. If it is not clear I can provide additional information, thank you so much for your time.
js:
setTimeout(function () {
const api_url_calories =
"https://api.spoonacular.com/recipes/634091/nutritionWidget.json";
// Defining async function
async function getapi(url) {
// Storing response
const response = await fetch(url);
// Storing data in form of JSON
var data = await response.json();
console.log(data);
data.calories.forEach((obj) => {
/*
create new DOM elements
*/
let div = document.createElement("div");
let calories = document.createElement("p");
div.append(calories);
/*
assign content from api data
*/
calories.innerHTML = obj.calories;
/*
add to DOM
*/
displayRecipes.append(div);
});
// if (response) {
// console.log("data here");
// }
}
getapi(api_url_calories);
}, 100);
HTML:
<body>
<div id="displayRecipes"></div>
</body>
The response from the api for the calories information is this:
{
"calories": "316",
"carbs": "49g",
"fat": "12g",
"protein": "3g",
"bad": [
{
"name": "Calories",
"amount": "316",
"indented": false,
"percentOfDailyNeeds": 15.84
},
js from the recipes request where the id comes from
const api_url =
"https://api.spoonacular.com/recipes/random?number=3";
// Defining async function
async function getapi(url) {
// Storing response
const response = await fetch(url);
// Storing data in form of JSON
var data = await response.json();
console.log(data);
data.recipes.forEach((obj) => {
/*
create new DOM elements
*/
let div = document.createElement("div");
let h1 = document.createElement("h1");
let image = new Image();
let cuisines = document.createElement("p");
let id = document.createElement("p");
div.append(h1);
div.append(image);
div.append(cuisines);
div.append(id);
/*
assign content from api data
*/
h1.innerHTML = obj.title;
image.src = obj.image;
for (let i = 0; i < 100; i++) {
cuisines.innerHTML = obj.cuisines;
}
// cuisines.innerHTML = obj.cuisines[0];
id.innerHTML = obj.id;
/*
add to DOM
*/
displayRecipes.append(div);
});
// if (response) {
// console.log("data here");
// }
}
// Calling that async function
getapi(api_url);
How the recipes data looks like, it has an id key.
"recipes": [
{
"vegetarian": false,
"vegan": false,
"glutenFree": false,
"dairyFree": false,
"veryHealthy": false,
"cheap": false,
"veryPopular": false,
"sustainable": false,
"weightWatcherSmartPoints": 1,
"gaps": "no",
"lowFodmap": false,
"aggregateLikes": 11,
"spoonacularScore": 21.0,
"healthScore": 1.0,
"creditsText": "Foodista.com – The Cooking Encyclopedia Everyone Can Edit",
"license": "CC BY 3.0",
"sourceName": "Foodista",
"pricePerServing": 12.65,
"extendedIngredients": [
{
"id": 1123,
"aisle": "Milk, Eggs, Other Dairy",
"image": "egg.png",
"consistency": "solid",
"name": "eggs",
"nameClean": "egg",
"original": "3 eggs, slightly beaten",
"originalString": "3 eggs, slightly beaten",
"originalName": "eggs, slightly beaten",
"amount": 3.0,
"unit": "",
"meta": [
"slightly beaten"
],
"metaInformation": [
"slightly beaten"
],
"measures": {
"us": {
"amount": 3.0,
"unitShort": "",
"unitLong": ""
},
"metric": {
"amount": 3.0,
"unitShort": "",
"unitLong": ""
}
}
},

You can achieve this with concatenation:
const recipe_id = "YOUR_DESIRED_ID";
const api_url_calories =
"https://api.spoonacular.com/recipes/" + recipe_id + "/nutritionWidget.json";

Related

how can i solve undefined in my code while pulling data from a REST API

i'm pulling data from a json file
[
{
"name": "Charlie S. Gerardi",
"avatar": "https://s3.amazonaws.com/uifaces/faces/twitter/brad_frost/128.jpg",
"id": 75,
"occupation": "Residential electrician"
},
{
"name": "Riley D. Norris",
"avatar": "",
"id": 23,
"occupation": "Transmission engineer"
}
]
when I console.log(data) am capable to see the json file
<script>
const api_url='https://api.airtable.com/v0/appBTaX8XIvvr6zEC/tblYPd5g5k5IKIc98?api_key=key4v56MUqVr9sNJv'
async function getAirtable() {
const response = await fetch(api_url);
const data = await response.json();
console.log(data.name)
console.log(data.id) //am not able to see the values in my consol//
console.log(data.avatar)
console.log(data.occupation)
}
getAirtable()
</script>
To access your data try this logic by looping through the items
const api_url = "https://api.airtable.com/v0/appBTaX8XIvvr6zEC/tblYPd5g5k5IKIc98?api_key=key4v56MUqVr9sNJv";
async function getAirtable() {
const response = await fetch(api_url);
const data = await response.json();
const allData = data.records.map((rec) => rec.fields);
// allData = [
// {
// Id: 79,
// Name: "Julia A. Robles",
// avatar:
// "https://s3.amazonaws.com/uifaces/faces/twitter/pixeliris/128.jpg",
// occupation: "Prosthodontist",
// },
// {
// Id: 29,
// Name: "Matthew H. Glover",
// avatar:
// "https://s3.amazonaws.com/uifaces/faces/twitter/flame_kaizar/128.jpg",
// occupation: "Transportation attendant",
// },
// ];
console.log(allData);
}
Based on your JSON, data is an array, so if you want to see everything, you need to iterate through the array such as
data.forEach(item => console.log(item.id))

How to fetch all data from API files and assign their values to chart?

I am trying to create a bubble chart that is going to show how many comments have been made in the files. However, my API doesn't provide the chunk of the information in one end-point, but it's more like a repository from which I have to fetch data from the different end-points. How should I approach this kind of thing?
const getData = async () => {
console.log("Processing");
const request = await fetch("http://25.102.238.73/api/repos/RxJava/");
const data = await request.json();
return data;
};
console.log(getData());
var popCanvas = document.getElementById("myChart");
Chart.defaults.global.defaultFontFamily = "Lato";
Chart.defaults.global.defaultFontSize = 18;
// y = Line of code in the file
// x = Line of comments in the file
var popData = {
datasets: [{
label: ['How many comments have been made in the code?'],
data: [{
x:getData(),
y:getData(),
r:getData()
},
],
backgroundColor: "#FF9966"
}]
};
var bubbleChart = new Chart(popCanvas, {
type: 'bubble',
data: popData
});
</script>
There are 2 problems in this code.
Problem 1: using async and sync code in one place. Here is an example snippet (for testing I removed fetch, but replaced it with its data, because your fetch is not working in snippet here).
Compare results of DATA1 and DATA2. The first one is sync, the second - async. You can see, that your sync variant is not working. So, you need async (using .then).
const getData = async() => {
//console.log("Processing");
//const request = await fetch("http://46.101.95.202/api/repos/RxJava/");
//const data = await request.json();
const data = {
"key": "RxJava", "name": "RxJava", "language": "java",
"path": "/RxJava_c", "links": { "self": "/api/repos/RxJava/" },
"contents": [{
"path": "/RxJava_c/docs", "name": "docs",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/docs"
},
{
"path": "/RxJava_c/gradle", "name": "gradle",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/gradle"
},
{
"path": "/RxJava_c/src", "name": "src",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/src"
}
]};
return data;
};
console.log("DATA1 =", getData());
getData().then((mydata) => {
console.log("DATA2 =", mydata);
});
Problem 2: even if we change sync code to be async, the data itself is not suitable for ChartJS. Look:
const getData = async() => {
//console.log("Processing");
//const request = await fetch("http://46.101.95.202/api/repos/RxJava/");
//const data = await request.json();
const data = {
"key": "RxJava", "name": "RxJava", "language": "java",
"path": "/RxJava_c", "links": { "self": "/api/repos/RxJava/" },
"contents": [{
"path": "/RxJava_c/docs", "name": "docs",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/docs"
},
{
"path": "/RxJava_c/gradle", "name": "gradle",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/gradle"
},
{
"path": "/RxJava_c/src", "name": "src",
"type": "directory",
"follow": "/api/repos/RxJava?data_path=/RxJava_c/src"
}
]};
return data;
};
getData().then((mydata) => {
//console.log(mydata);
var popCanvas = document.getElementById("myChart");
Chart.defaults.global.defaultFontFamily = "Lato";
Chart.defaults.global.defaultFontSize = 18;
// y = Line of code in the file
// x = Line of comments in the file
var popData = {
datasets: [{
label: ['How many comments have been made in the code?'],
data: [{
x: mydata,
y: mydata,
r: mydata
},
],
backgroundColor: "#FF9966"
}]
};
var bubbleChart = new Chart(popCanvas, {
type: 'bubble',
data: popData
});
});
<script src="https://cdn.jsdelivr.net/npm/chart.js#2.8.0"></script>
<canvas id="myChart">

Looping through object

I am doing an exercise using swapi co API, and after I fetched results from the website but I want to display only some of API objects. For the moment I am struggling with displaying all array spaceships.
var linkApi="https://swapi.co/api/starships"
async function starships()
{
let response = await fetch(linkApi);
let data = await response.json()
for(i=0; i<data.results.length;i++){
return{
"count": data.count,
"results":[
{
"name":data.results[i].name,
"model": data.results[i].model,
"crew":data.results[i].crew,
}
]
}
}
}
starships()
.then(data => console.log(data));
this is the format that I want to achive
{
"count": "",
"results": [
{
"name": "",
"model": "",
"crew": "",
"passengers": "",
"films_count": "",
"films": [
{
"title": "",
"director": "",
"release_date": ""
}
]
}
]
}
The return will finish your function returning just the first spaceship info. You should create an object outside the for loop and after the for ends pass it an array with all the spaceships in the format you want
var linkApi="https://swapi.co/api/starships"
async function starships()
{
let response = await fetch(linkApi);
let data = await response.json()
let spaceshipsArray = [];
let result = {
"count": data.length
};
for(i=0; i < data.results.length;i++){
spaceshipsArray.push({
"name":data.results[i].name,
"model": data.results[i].model,
"crew":data.results[i].crew,
});
}
}
result.results = spaceshipsArray;
return result;
}
It would be something like that.

Postman JSON parse response body arrays inside arrays

I have this JSON Response from API call
[
{
"id": 20599,
"name": "Deliver",
"options": [
{
"id": 63775,
"name": "Item",
"dataType": "SelectMultiOption",
"required": false,
"options": [
{
"id": 426,
"name": "Towels"
},
{
"id": 427,
"name": "Toothbrush"
},
{
"id": 428,
"name": "Pillow"
}
]
}
]
}
]
I am using this code to get the id of the service "Deliver"
var data = JSON.parse(responseBody);
var loop_count = 0
for (count = 0; count < data.length; count++)
{
if (data[count].name == "Deliver")
{
var job_id = data[count].id;
postman.setEnvironmentVariable("service_id", job_id);
}
}
The questions are:
How can I get value from array "options", I need to get the "id":
63775 and store as "item_id" and the "name":"Item" as "item_name" postman variables.
Then I need to select the "options" nested in record
"Item" and select the option "name": "Toothbrush" and store in postman
variable "svc_optn_optn_name" and it's "id" stored in
"svc_optn_optn_id"
Here I am giving my own suggestion for your problem with few lines of code. I am not sure, how are you going to use these values. I also don't know if the outer options array will always have 1 item or more. I have just tried to satisfy your questions.
Please ask/comment, if you have more doubts or I am wrong.
I have created a function getAllPostmanDataFrom(obj) which takes object as parameter which is the value of data[count], gathers necessary info in other object postmanObj and returns it to the caller.
function getAllPostmanDataFrom(obj) {
const item_id = obj.options[0].id;
const item_name = obj.options[0].name;
const svc_optn_optn_name = obj.options[0].options[1].name;
const svc_optn_optn_id = obj.options[0].options[1].id;
const postmanObj = {item_id, item_name, svc_optn_optn_id, svc_optn_optn_name}; // Return object
return postmanObj;
}
var data = [
{
"id": 20599,
"name": "Deliver",
"options": [
{
"id": 63775,
"name": "Item",
"dataType": "SelectMultiOption",
"required": false,
"options": [
{
"id": 426,
"name": "Towels"
},
{
"id": 427,
"name": "Toothbrush"
},
{
"id": 428,
"name": "Pillow"
}
]
}
]
}
]
var count = 0;
var obj = data[count];
var postmanObj = getAllPostmanDataFrom(obj);
//var {item_id, item_name, svc_optn_optn_id} = postmanObj;
console. log(postmanObj)
/*
console.log(item_id);
console.log(item_name);
console.log(svc_optn_optn_id);
console.log(svc_optn_optn_name);
*/
Finally, you can use values contained in postmanObj as follows:.
postman.setEnvironmentVariable("item_id", postmanObj.item_id);
postman.setEnvironmentVariable("item_name", postmanObj.item_name);
And so on.
This is the solution
var data = JSON.parse(responseBody);
variable named as data
var loop_count = 0
for (count = 0; count < data.length; count++)
{
if (data[count].name == "Deliver")
{
var job_id = data[count].id;
postman.setEnvironmentVariable("service_id", job_id);
var job1_name = data[count].options[0].name;
postman.setEnvironmentVariable("item_name", job1_name);
var job2_id = data[count].options[0].id;
postman.setEnvironmentVariable("item_id", job2_id);
var job3_id = data[count].options[0].options[1].id;
postman.setEnvironmentVariable("svc_optn_optn_id", job3_id);
var job4_name = data[count].options[0].options[1].name;
postman.setEnvironmentVariable("svc_optn_optn_name", job4_name);
}
const data = JSON.parse(responseBody);
data.forEach(item => {
console.log(item.id); // deliver object id.
item.options.forEach(option => {
console.log(`Option Id ${option.id}`); // option id
postman.setEnvironmentVariable("service_id", option.id);
option.options(optionItem => {
if(optionItem.name == 'Toothbrush'){
postman.setEnvironmentVariable("svc_optn_optn_name", optionItem.name);
postman.setEnvironmentVariable("svc_optn_optn_id", optionItem.id);
}
});
});
});

Creating Tableau WDC from associative array

I am creating a Tableau Web Data Connector as described in their Getting Started guide HERE.
I have implemented a similar solution previous with data from a basic associative array, but I am having trouble with my current API call.
I make an API call to an external web service that returns a JSON similar to the one listed below (simplified version)(COMMENT simply added for clarity and not part of original code).
{
"status": true,
"employee": {
"id": 123
},
"company": {
"id": 123
},
"job": {
"id": 123,
"job_workflows": [{
"id": 1,
"name": "Start",
"action_value_entered": "Start"
}, {
"id": 2,
"name": "Date",
"action_value_entered": "2017-09-11"
}, {
"id": 3,
"name": "Crew",
"action_value_entered": "Crew 3"
},
**COMMENT** - 17 other unique fields - omitted for brevity
]
}
}
For my requirements, I need to create a new column for each of my JSON job_workflows to display the data in Tableau. I.e.
Column 1 Header = Start
Column 1 value = Start
Column 2 Header = Date Complete
Column 2 value = 2017-09-11
Etc.
My Tableau JavaScript file looks as below:
(function () {
var myConnector = tableau.makeConnector();
myConnector.init = function(initCallback) {
initCallback();
tableau.submit();
};
myConnector.getSchema = function (schemaCallback) {
var cols = [
{ id : "start", alias : "Start", dataType: tableau.dataTypeEnum.string },
{ id : "date", alias : "Date", dataType: tableau.dataTypeEnum.datetime },
{ id : "crew", alias : "Crew", dataType: tableau.dataTypeEnum.string }
];
var tableInfo = {
id : "myData",
alias : "My Data",
columns : cols
};
schemaCallback([tableInfo]);
};
myConnector.getData = function (table, doneCallback) {
$.getJSON("http://some/api/call/data.php", function(response) {
var resp = response; // Response is JSON as described above
var tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
// not working
tableData.push({
"start": resp.job.job_workflows[i].action_value_entered,
"date": resp.job.job_workflows[i].action_value_entered,
"crew": resp.job.job_workflows[i].action_value_entered
});
}
table.appendRows(tableData);
doneCallback();
});
};
tableau.registerConnector(myConnector);
})();
How do I iterate over the JSON job_workflow and assign each action_value_entered to be a id in my getSchema() function? My current version simply hangs and no values are returned. NO error or warnings thrown.

Categories