I'm making a Trivia Game and I'm using The Open Trivia Database to generate 10 random questions.
These 10 questions are separate strings and I want to place them into an array so that I can display them one by one (after the user guesses whether it's True or False.)
Here is the console log of the questions:
Now here is what I'm trying: I have initialized an empty array and then, in the for loop, I'm pushing each question into the array but its not working.
Essentially, what I'm trying to achieve is that when the user clicks a true or false button, the next item in the response will be displayed. I thought an array would work but maybe I'm looking at it in the wrong way.
Any help is appreciated and if I missed something, please let me know. Thank you in advance!
Code:
const api_url =
"https://opentdb.com/api.php?amount=10&difficulty=easy&type=boolean";
const triviaQ = document.getElementById("triviaQuestion");
const question_array = []; // this is the empty array
async function getAPI(url) {
const response = await fetch(url);
var data = await response.json();
justQuestions(data);
}
function justQuestions(data) {
/// loop to display all 10 questions
for (let i = 0; i <= 9; i++) {
display_all_questions = data.results[i].question;
current_question = triviaQ.innerHTML = display_all_questions; /// the console log image
let all_questions = question_array.push({ display_all_questions }); //this is where I attempt to add the questions into an array
}
}
First, you are creating a variable 'all_questions' on each iteration and never use it (you don't need it). Second, 'display_all_questions' name is misleading, as it is just the current question.
And finally, your data.results is already the array that you need, so you can just use it like this:
let questions_array = [];
async function getAPI(url) {
const response = await fetch(url);
var data = await response.json();
questions_array = data.results;
console.log(questions_array);
}
Don't forget to handle possible network request errors
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
I hope this is not a duplicate. So far I could find a few tutorials and questions about this - but usually everyone just wants to log the results of their code to console, which is not helping me.
I want to fetch some data from an API to plot it on a website.
The fetching seems to work fine, because I can log the results inside the fetch.then() to the console. But (obviously) they do not make their way outside of the fetch.
The only solution I was able to find is to wrap this whole thing in another function or to write a function that works with the data fetched inside of the .then().
I couldn't make the first idea work, because I cannot return anything for the same reason as above (the data does not make it's way outside of the .then()).
The second one is problematic, because I simply want to plot the results from a few .json entries to a Plotly plot. And I have honestly no idea how to place this inside of a function.
// Arrays for results
var sugars = [];
var times = [];
// fetch the BG data from the API and write results into arrays
fetch(url)
.then((resp) => {return resp.json()})
.then( (result) => {
// read glucose values from json
// logging the results/sugars/times to console from here works!
for (let i = 0; i < n_entries; i++) {sugars[i] = result[i]["sgv"]}
for (let i = 0; i < n_entries; i++) {times[i] = -i * timestep}
});
var x1;
var y1;
/*
// Dummy data to test plotly, these WORK for some reason.
x1 = [0, -5, -10, -15, -20];
y1 = [123, 119, 113, 107, 102];
*/
// These values, however, don't work:
/*
x1 = times;
y1 = sugars;
// this yields 'undefined' errors:
console.log(times)
*/
Maybe you can try to separate your fetch and return the data to a function where you use the data to do what you want. You can try something like this - I think it is the same as what other people commented.
//make the fetch and return response data as json
async function getData() {
let url = 'your url';
try {
let resp = await fetch(url);
return await resp.json();
} catch (error) {
console.log(error);
}
}
//do whatever you want with the data response
async function myFunc() {
let data = await getData();
//do some stuff with your data here
}
//call the function
myFunc();
Take at look at this link if you get stuck.
I would like to check if axios request already fetched certain data.
On first call i get 10 elements and store them in array. On second request i would like to check if existing data is in array, if yes do not add them again and if they are not in array add them.
It is written in Vuejs.
.then((response) => {
this.receivedData = response.data
for( let i = 0; i < this.receivedData.length; i++) {
let receivedDataArray = [];
receivedDataArray.push(this.receivedData[i].id);
if(!receivedDataArray.includes(this.receivedData.id)) {
receivedDataArray.push(this.receivedData);
receivedDataArray = this.receivedData;
}
}
})
But i can not find an error. Please advise.
You are overwriting the values you pushed into receivedDataArray on
receivedDataArray = this.receivedData;
Basicly, resetting it on every loop, so after the for ends, you have the response.data in receivedDataArray
Edit: Also you are not using the [i] index inside your if
I have added comments to help follow my logic below. I believe all issues I can see with the code have been pointed out in other comments, so will just provide my solution to this answer.
It is untested, but hope that it helps.
.then((response) => {
// If data has not already been added to receivedData, this is the first loop.
if (!this.receivedData) {
// So store the response
this.receivedData = response.data;
return;
} else {
for(const item of reponse.data) {
//
if(!this.receivedData.includes(response.data[item])) {
// If not, push it to the array
this.receivedDataArray.push(response.data[item]);
}
}
}
})
I'm using Axios to scrape JSON product data from a website. The script below first requests category data from server and loops through three hierarchies of categories, subcategories, and (I guess) sub-subcategories. In the third loop, the sub-subcategories query parameter is used as a parameter in a function call, which calls an asynchronous function which uses this query parameter to concatenate onto the URL to make the new URL, make a GET request for the product data related to the query parameter, and loop this until the the pageCounter iteration variable (which is used as a pagination query parameter to get N pages for each new URL) is equal to the pagination value within the current new url containing the sub-subcategory query parameter.
for (let i=0; i<obj.length; i++) {
let subcats = obj[i].subcategories.length;
for(let n=0; n<subcats; n++) {
if(obj[i].subcategories[n].facetValueData) {
let subsubcats = obj[i].subcategories[n].facetValueData.length
for(let p=0; p<subsubcats; p++) {
let productData = []
obj[i].subcategories[n].facetValueData[p].productData = productData
const scrapedData = await scrapeData(obj[i].subcategories[n].facetValueData.code)
obj[i].subcategories[n].facetValueData[p].productData.push(scrapedData)
}
} else {
console.log(`No facet values present - ${obj[i].subcategories[n]}`)
}
}
}
This is the async function that the third loop calls
async function scrapeData(queryParam) {
var product = []
var pagination;
try {
do {
var nextPageLink = `currentPage=${pageCounter}&query=::cagCollectionPoint:Departure+from+Singapore:cagCategory:${queryParam}`
var nextUrl = url.concat(nextPageLink)
const response = await axios({
method: "GET",
url: nextUrl,
withCredentials: true,
headers: headers
})
product = response.data["products"]
pagination = response.data["pagination"]["totalPages"]
pageCounter++;
//this logs all of the correct current queries
console.log(response.data.currentQuery.query.value)
} while (pageCounter<=pagination)
return product
} catch (error) {
console.error(error)
}
}
At first glance it appears as if it is working, as it populates the first few sub-subcategory objects with an array of products scraped, however some of these are not populated, i.e. productData = []
The console log function in the scrapeData function returns all of the correct current queries per iteration, however when they are returned it only returns the first few reponses.
I'm guessing the product array needs to wait? But the axios request is already awaited, so i dont see why this is happening.
If I'm understanding your intent on this piece of code correctly:
var product = [];
do {
// ...
const response = await axios(/* ... */);
product = response.data["products"]
// ...
} while (pageCounter<=1)
return product
it seems like there are multiple pages, and you want to get all of them into the product array?
But in reality, each page you are replacing the product array. I would assume that on the empty ones your last fetch gets no results, and you are just losing all of the rest of them.
What you probably want to do is just change the product = response.data["products"] to:
product.push(...response.data["products"])
I'm generating PDF by using https://pdfgeneratorapi.com/.
Now I can show data one by one using this code.Can any one give me suggestion how can show all data with loop or any other way?
This below photos showing my template from pdfgenerator .
This is the code I'm using to generate PDF
let communicationWay1=[
{0:"dim"},
{1:"kal"}
];
let cstomerExpence1=[
{0:"dim"},
{1:"kal"}
];
let title="test";
let names="test";
let phone="test";
let email="test";
let maritalStatus="test";
let city="test";
let other="test";
const result = await wixData.query(collection)
.eq('main_user_email', $w('#mainE').text)
.find()
.then( (results) => {
if (results.totalCount>0) {
count=1;
// title=results.items[1].title;
names=results.items[0].names;
email=results.items[0].emial;
phone=results.items[0].phone;
maritalStatus=results.items[0].maritalStatus;
city=results.items[0].city;
other=results.items[0].cousterExpenses_other;
title=results.items[0].title;
communicationWay=results.items[0].communicationWay;
cstomerExpence=results.items[0].cstomerExpence;
}
if (results.totalCount>1) {
names1=results.items[1].names;
email1=results.items[1].emial;
phone1=results.items[1].phone;
maritalStatus1=results.items[1].maritalStatus;
city1=results.items[1].city;
other1=results.items[1].cousterExpenses_other;
title1=results.items[1].title;
communicationWay1=results.items[1].communicationWay;
cstomerExpence1=results.items[1].cstomerExpence;
}
} )
.catch( (err) => {
console.log(err);
} );
// Add your code for this event here:
const pdfUrl = await getPdfUrl
({title,names,email,phone,city,maritalStatus,other,communicationWay,cstomerExpence,title1,
names1,email1,phone1,city1,maritalStatus1,other1,communicationWay1,cstomerExpence1
});
if (count===0) { $w("#text21").show();}
else{ $w("#downloadButton").link=wixLocation.to(pdfUrl);}
BELOW CODE IS BACKEND CODE/JSW CODE.
Also I want to open pdf in new tab. I know "_blank" method can be used to open a new tab.But I'm not sure how to add it with the url
import PDFGeneratorAPI from 'pdf-generator-api'
const apiKey = 'MYKEY';
const apiSecret = 'MYAPISECRET';
const baseUrl = 'https://us1.pdfgeneratorapi.com/api/v3/';
const workspace = "HELLO#gmail.com";
const templateID = "MYTEMPLATEID";
let Client = new PDFGeneratorAPI(apiKey, apiSecret)
Client.setBaseUrl(baseUrl)
Client.setWorkspace(workspace)
export async function getPdfUrl(data) {
const {response} = await Client.output(templateID, data, undefined, undefined, {output: 'url'})
return response
}
Just put it in a while loop with a boolean condition.
You can create a variable, for example allShowed, and set its value to False. After that, create another variable, for example numberOfDataToShow, and set it as the number of elements you want to display. Then create a counter, countShowed, initialized with 0 as its value.
Now create a while loop: while allShowed value is False, you loop (and add data).
Everytime a piece of your data is showed, you increment the value of countShowed (and set it to go on adding/showing data). When countShowed will have the exact same value of numberOfDataToShow, set allShowed to True. The loop will interrupt and all your data will be showed.
You would need to use the Container or Table component in PDF Generator API to iterate over a list of items. As #JustCallMeA said you need to send an array of items. PDF Generator API now has an official Wix Velo (previously Corvid) tutorial with a demo page: https://support.pdfgeneratorapi.com/en/article/how-to-integrate-with-wix-velo-13s8135
So I'm trying to retrieve the URLs for three images from the database, then store them in an object like this:
let pics = {
zero: "url0.jpg",
one: "url1.jpg",
two: "url2.jpg"
}
So I can then transfer them to an array in a specific order like so:
let picsArray = [pics.zero, pics.one, pics.two]
However, the following code is giving a bizarre result in the console...
let currentUser = firebase.auth().currentUser
let pics = {}
firebase.storage().ref(currentUser.uid).listAll().then(results => {
results.items.forEach(async imageRef => {
let meta = await imageRef.getMetadata()
let order = meta.customMetadata.order
let url = await imageRef.getDownloadURL()
pics[order] = url
})
console.log(pics)
console.log(pics.zero)
console.log(pics.one)
console.log(pics.two)
}).catch(err => console.log(err))
...displaying the correct object as expected from the first console.log, but then displaying 'undefined' for each of the following three. How is this even possible, given the object was recognised and logged on literally the previous line?