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]);
}
}
}
})
Related
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
I'm performing multiple task and each task is dependent on previous task execution. So in my example what I want is after getting all the Id, i should get their respective blob value and then finish the execution by storing it in a variable. I'm very new to javascript and angular, please help me out. Here's what I'm trying
//this method will get the response from the rest api
async getIDFromAssets(){
this.blobDataArray=[];
this.service.getAssetsData().subscribe(async (res: JSON) => {
//after getting the response I'm filtering through it to get sepcific Id using this.getFileId() method
this.getFileId(res).then((data)=>{
console.log("blob "+data)
})
})
}
//below method will get one Id at a time and will call another method to get it's blob value
async getFileId(res){
this.fileId = [];
Object.keys(res).forEach(keys => {
if (keys == 'emb') {
let responseValue = res[keys];
Object.keys(responseValue).forEach(async (keys1) => {
if (keys1 === 'file') {
let responseArray = responseValue[keys1];
for (let file of responseArray) {
let temp: string = file.metadata.contentType;
if (temp.startsWith('image')) {
//Here I'm getting id value 'file._id' and using that I'm calling another method 'getBlobData()' to get its blob value
let data=await this.getBlobData(file._id);
this.blobDataArray.push(data);
}
}
return this.blobDataArray
}
});
}
});
}
// method to get the blob value
async getBlobData(fileId){
this.articleDetailService.getBlobDataFromAssets(fileId).subscribe(async (res)=>{
let imageObj={
'id':fileId,
'blob':res
}
return imageObj;
})
}
You need to use RxJs to avoid the nested subscription to chain your calls, possible methods to use are mergeMap and filter
Please take a look at this answer here.
I come from C++, C, Python space and I'm new to react native / JS / back-end world.
I have some issues loading data from firebase. Here is what I want :
My Database :
users : uid : postids[]
posts : postids : content
I want to load the postids[] array from a user and then, load content of every postids[] in this array (according to every postids in the postids[] array).
Here is my code :
_getPostsFromDatabase() {
var docRef = firebase.firestore().collection("users").doc(firebase.auth().currentUser.uid);
return docRef.get().then(function(doc) {
if (doc.exists) {
return doc.data()["posts"];
}
}).catch(function(error) {
alert("Error getting document:", error);
});
}
_loadPosts() {
var new_posts = [];
this._getPostsFromDatabase()
.then(res => {
var i;
for (i = 0; i < res.length; i++) {
firebase.firestore().collection("posts").doc(res[i])
.onSnapshot(function(doc) {
new_posts.push(doc.data());
console.log(new_posts); --> This line print correct data
});
}
})
.catch(error => console.log(error));
console.log(new_posts); ---> This line print an empty array
}
componentDidMount() {
this._loadPosts()
}
So I want this behavior :
In componentDidMount I begine the routine --> this works
loadPosts is loading the postids[] array with _getPostsFromDatabase() function --> this works
Then, I make a for loop to push every object in an array to set the state at the end --> FAIL
At step 3, everything f... up, I made some console log to debug but there is a huge real time issue because evrything is printed randomly.
How can I get my new_posts filled array at the end of the for loop to setState. Maybe I'm wrong with this method, or if I'm not, I must have some issues with Async funtion ?
Is there an expert to help me understund better what is inside this kind of use case ?
Thanks
Basically the problem is that you are trying to perform an asynchronous code in a synchronous way.
You solution might be waiting for all promises to resolve.
_loadPosts() {
this._getPostsFromDatabase()
.then(res => {
let promises = res.map(id => {
return firebase.firestore().collection("posts").doc(id)
.get().then(doc => doc.data())
})
Promise.all(promises).then(res => {console.log(res);})
}
Your console will log before the for loop, that's the reason you are getting an empty array just include your console in the response just like this:
this._getPostsFromDatabase()
.then(res => {
var i;
for (i = 0; i < res.length; i++) {
firebase.firestore().collection("posts").doc(res[i])
.onSnapshot(function(doc) {
new_posts.push(doc.data());
console.log(new_posts); --> This line print correct data
});
}
console.log(new_posts); ---->Include here
})
Hope this helps!
I am trying to refresh my page on delete and refresh button, it gets new data but the issue is new data will add to old ones I need to clear old data before adding new data.
Code
addresses: any[] = [];
// loads first time data
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
// refresh list items
doRefresh(event) {
console.log('Begin async operation');
setTimeout(() => {
console.log('Async operation has ended');
// get new items in list
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
event.target.complete();
}, 2000);
}
//remove item and renew list items
removeAddress(id: string){
this.addressService.remove(id).subscribe(
data => {
this.alertService.presentToast(data['message']);
//getting items (renew)
this.addressService.getAddresses().subscribe((res) => {
for (let address of res['data']) {
this.addresses.push(address);
}
this.hideLoading();
});
},
error => {
this.alertService.presentToast(error['message']);
}
);
}
I think that I need to clear addresses: any[] = []; before getting
new items in my doRefresh(event){..} and removeAddress(id:
string){...} functions to avoid duplicates.
Any idea?
Assuming your refresh function works,
add this code before you get new items from your api
this.addresses =[];
or
this.addresses.length = 0;
For implementation wise, in regards to delete function, you can delete from your backend , clear your array and pull a fresh set of data which might be costly if you have a huge dataset.
You might want to consider updating your backend (delete that specific data) and removing that specific index from your array (when your delete function returns success)
For update, you can do a comparison and update those those array objects that has been modified. Else you can just clear your array and retrigger your retrieve api function.
In a Chrome extension im using the HTML5 FileSytem API.
Im retrieving a list of records in a folder.
var entries = [];
var metadata = [];
listFiles(folder);
function listFiles(fs) {
var dirReader = fs.createReader();
entries = [];
// Call the reader.readEntries() until no more results are returned.
var readEntries = function () {
dirReader.readEntries(function (results) {
if (!results.length) {
addMeta(entries);
} else {
console.log(results);
entries = entries.concat(toArray(results));
readEntries();
}
});
};
readEntries(); // Start reading dirs.
}
The FileEntry object does not contain metadata, I need the last modified date. I'm able to retrieve a object of metadata
function addMeta(entries) {
for (var i = 0; i < entries.length; i++) {
entries[i].getMetadata(function (metadata) {
console.log(entries);
console.log(metadata);
});
}
}
Problem is that i get the metadata in a callback.
How can i join the two object making sure the right match is made?
The simplified result im looking for is:
[
["fileName1", "modifyDate1"],
["fileName2", "modifyDate2"],
]
To get lastModifiedDate, you don't need to use getMetadata, as per the description of this question, just use entry.file.lastModifiedDate, though maybe file() is another callback.
To "join the two object making sure the right match is made", because of Closures, you could use the following code to get the right results. (Assuming the data structure is [[entry, metadata]] as you mentioned)
var ans = [];
function addMeta(entries) {
for (var i = 0; i < entries.length; i++) {
(function(entry) {
entry.getMetadata(function (metadata) {
ans.push([entry, metadata]);
});
}(entries[i]);
}
}
If what you want is to wait for all asynchronous callback ends, see this answer for more details, basically you could adjust your code and use Promise, or use other implementations like setInterval or use a variable to calculate how many callbacks remain.
I suggest to have a look on Promise-based bro-fs implementation of HTML Filesystem API.
To read all entries with metadata you can do something like this:
fs.readdir('dir')
.then(entries => {
const tasks = entries.map(entry => fs.stat(entry.fullPath))
return Promise.all(tasks);
})
.then(results => console.log(results))