Looping through object - javascript

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.

Related

Adjust a 22-line JS function that now returns wrong counts with +1 / +2 differences for no reasons

My function further below seems fine yet the count is overstated in some instances, eg: should count '1' but shows '2'.
Data source for context:
{
"currency": "USD",
"services": [
{
"category": [
{"token": "token1"},
{"token": "token2"}
],
"price": 149
},
{
"category": [
{"token": "token3"},
{"token": "token4"}
],
"price": 149
}
]
},
{
"currency": "EUR",
"services": [
{
"category": [
{"token": "token1"},
{"token": "token2"}
],
"price": 149
},
{
"category": [
{"token": "token3"},
{"token": "token4"}
],
"price": 149
}
Goal: COUNT the frequency of category tokens per price, sorted by currency in their own objects.
Desired output schema (for illustration purposes, unrelated to above schema example):
{
"result": [
{
"currency": "USD",
"token": "Wellness",
"count": 1,
"price": 100
},
{
"currency": "USD",
"token": "Adventure",
"count": 1,
"price": 300
}
]
}
It appears that sometimes, the count is not right, by +1 or +2 difference for no apparent reasons.
My function, which outputs wrong counts:
const data = inputs.data;
const result = [];
let error = null;
try {
data.forEach(item => {
item.services.forEach(service => {
service.category.forEach(tokenObject => {
const token = tokenObject.token;
const existingToken = result.find(item => item.token === token && item.price === service.price && item.currency === item.currency);
if (existingToken) {
existingToken.count++;
} else {
result.push({currency: item.currency, token, count: 1, price: service.price});
}
});
});
});
} catch (e) {
error = "error";
}
return error ? [1, {error}] : [0, {result}]
Any way to make it "fool-proof" with some kind of "UNIQUE" safe guard?
Note: I'm beginner in JS.
I've used OpenAI's playground and it gave me the right function!
It suggested to "modify the existing code to use a Map data structure instead of an array to store the token count information. The Map will allow to keep track of each token, currency, and price combination as a key, and its count as the value"
const data = inputs.data;
const result = [];
let error = null;
try {
const tokenMap = new Map();
data.forEach(item => {
item.services.forEach(service => {
service.category.forEach(tokenObject => {
const token = tokenObject.token;
const key = `${token}-${service.price}-${item.currency}`;
if (tokenMap.has(key)) {
tokenMap.set(key, tokenMap.get(key) + 1);
} else {
tokenMap.set(key, 1);
}
});
});
});
tokenMap.forEach((count, key) => {
const [token, price, currency] = key.split('-');
result.push({currency, token, count, price: Number(price)});
});
} catch (e) {
error = "error";
}
return error ? [1, {error}] : [0, {result}]

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

moving a key value pair out of an array

I am trying to move everything in the Array Results outside and into the original object
this is the object
{
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
It should look like this
{
"Name": "John",
"Type": "DB",
"Immediate_Action": "No",
}
What I have so far is this
const mapOscarResults = ({ data }) => {
return data.map(entry => {
let mapped = {...entry};
entry.Results.forEach(key => {
let Type = mapped[key.Type]
if (mapped[key]) {
mapped[key].push(entry.Results[key]);
} else {
mapped[key] = [entry.Results[key]];
}
});
return mapped;
});
};
You can simply spread the Results array into an Object.assign() call.
const input = { "Name": "John", "Results": [{ "Type": "DB", "Immediate_Action": "No", }, { "Another": "value" }] };
const { Results, ...refactored } = input;
Object.assign(refactored, ...Results);
console.log(refactored)
This code works for your example:
const { Results: results, ...rest } = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const res = {...rest, ...results.reduce((prev, curr) => ({
...prev,
...curr
}), {})}
console.log(res)
But I don't know what you expect when the Results array has more than one element.
In that condition, if this code does not fill your needs, ask me to change it.
however, it will join first Result with index 0, you can expand it
const data = {
"Name": "John",
"Results": [
{
"Type": "DB",
"Immediate_Action": "No",
}
]
}
const mapOscarResults = (data) => {
for (let i in Object.keys(data)){
if (Array.isArray(data[Object.keys(data)[i]])){
newKey = data[Object.keys(data)[i]][0]
data = {... data, ...newKey}
delete data[Object.keys(data)[i]]
}
}
return data
};
console.log(mapOscarResults(data))

Create JSON dynamically with dynamic keys and values in Express Js

I am fetching API into my Express server which has several JSON key value pairs in one array.
For Example:
[{
"quality": "best",
"url": "https://someurlhere.example/?someparameters"
},
{
"quality": "medium",
"url": "https://someurlhere1.example/?someparameters"
}]
And I want to create an array of JSON of that received data in this Format:
[{
"best": "https://someurlhere.example/?someparameters"
},
{
"medium": "https://someurlhere1.example/?someparameters"
}]
I have tried doing this by using for loop
for(let i=0; i < formats.length; i++){
arr.push({
`${formats[i].quality}` : `${formats[i].url}`
})
}
But it didn't work for me.
Please help me in achieving this.
Thanks in Advance :)
You could use the map function and create a new object from it.
For example:
let prevArr = [{
"quality": "best",
"url": "https://someurlhere.example/?someparameters"
}, {
"quality": "medium",
"url": "https://someurlhere1.example/?someparameters"
}]; // Replace with your array
let newArr = [];
let obj = {};
prevArr.map(function(x) {
obj = {};
obj[x["quality"]] = x.url;
newArr.push(obj);
});
const input = [{
"quality": "best",
"url": "https://someurlhere.example/?someparameters"
}, {
"quality": "medium",
"url": "https://someurlhere1.example/?someparameters"
}];
const result = input.map((v, i) => {
return {
[v["quality"]]: v["url"]
}
});
console.log(result)

Insert dynamic id into api request link to display data

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

Categories