.push() is not working outside of the for loop - javascript

I have already handled a response from an API call. I then export the data into a function that i'm using a for loop inside. The const diomerda is passed to the ejs file where i am outputting the array data from the API. However the data in the array is over 5000 entries, so i want to run a for loop to populate the ejs file with the entire array. But when I use loop.push it does not populate the const loop. console.log(loop) just reads [].
Once the const loop = [] is populated with the array i was then going to pass the data into the const diomerda = [json.entries[loop].character.name]
I'f anyone has any other ideas on how to acheive what i'm trying to do then please feel free to send away. Thanks in advance.
.then(response => response.json())
.then(json => ejsoutput(json))
}
function ejsoutput(json) {
const loop = []
console.log(loop)
const diomerda = [json.entries[0].character.name, json.entries[1].character.name, json.entries[2].character.name]
for (var i = 0; i < json.entries.length; i++) {
loop.push(i)
}
res.render('index', {
leaderboard: diomerda
})
}
});

Once the const loop = [] is populated with the array i was then
going to pass the data into the const diomerda = [json.entries[loop].character.name]
If what you want is to populate diomerda with each character name return from the api, do this
function ejsoutput(json) {
const diomerda = [];
for (var i = 0; i < json.entries.length; i++) {
diomerda.push(json.entries[i].character.name);
}
console.log(diomerda);
}
OR in simpler terms
function ejsoutput(json) {
const diomerda = json.entries.map(item => item.character.name);
console.log(diomerda);
}

To debug, print (log) the json object, instead of the empty loop array (shoule get you on track).
Json should be a promise. That's probably what you're running into.
See: https://developer.mozilla.org/en-US/docs/Web/API/Response/json
Try something like
json().then(function(json) {
});

Related

How to correctly pass parameters through nested functions in for loop?

I'm trying to use nodejs to run a loop functions oh_lawd_it_chonky() that is supposed to do the following: Loop target_users array passing each user to initialize() for authorization, for each given user get data using returnbigdatachunk() take that data and refine it or do something to it using process_returnbigdatachunk() push each of the results of that for each user to an array output.
I have each of the initialize(), returnbigdatachunk() and process_returnbigdatachunk() working individually and so I've omitted the details of those functions for the sake of simplicity in this post, I just can't seem to get the darn oh_lawd_it_chonky() function working. I don't quite understand how to pass through the user parameters correctly in nested functions like this. Please help if you can! Sorry this isn't quite a working example.
const target_users = ['user1', 'user2', 'user3'];
//authorize each user
function initialize(user) {
//do the stuff to get authorization
}
//loop through all the users and build an array of all the process_returnbigdatachunk
const oh_lawd_it_chonky = async () => {
for (var f = 0; f < target_users; f++) {
try {
//get data of passed in user
const returnbigdatachunk = async () => {
const auth = initialize(user[target_users[f]]);
let output = [];
//refine data of passed in user
const process_returnbigdatachunk = async () => {
try {
const data = await returnbigdatachunk();
//push refined data into output array
output.push(process_returnbigdatachunk)
console.log("crampus: " + output)
} catch (e) {
console.error('Failed to process returnbigdatachunk', e);
}
};
};
} catch (e) {
console.error('Failed to process returnbigdatachunk', e);
}
}
};
setTimeout in for-loop does not print consecutive values
block-scoped
change you var f = 0 to let f = 0

how to deal with firebase onsnapshot as an object or array?

im doing orders onsnapshot from firebase but im confused how to deal with it, I get an [] when I log it out but when I logout the type of orders it says object,
I'm trying to add the id of each order and place it inside the array orders along with the existing data but its not working , if I
console.log(orders[0]) I get undefined and if I treat it as an object orders['0'] i also get undefined.
here is the code:
im using vuejs mounted
async mounted() {
let id = [];
let orders = [];
await db.collection("orders").onSnapshot(doc => {
doc.docs.forEach(x => {
id.push(x.id);
orders.push(x.data());
});
});
for (order in orders) {
let i = 0;
order.id = id[i];
i++
}
console.log(orders);
}}
the result of this code is the same orders array without any change at all.
Data is loaded from Firestore asynchronously. While that is happening, your main code continues to execute, so that the user can continue to use the app.
What this means in practice is that in your code the console.log(orders) is executed before any of the orders.push(x.data()) is ever run.
The solution is pretty simple: any code that needs the data from the database, needs to be inside the callback that is called with the data:
async mounted() {
let id = [];
let orders = [];
db.collection("orders").onSnapshot(doc => {
doc.docs.forEach(x => {
id.push(x.id);
orders.push(x.data());
});
for (order in orders) {
let i = 0;
order.id = id[i];
i++
}
console.log(orders);
});
}
}
Alternatively, you can use async and await to handle the asynchronicity, but in that case you should use get instead of onSnapshot and not use a callback:
async mounted() {
let id = [];
let orders = [];
const snapshot = await db.collection("orders").get();
snapshot.docs.forEach(x => {
id.push(x.id);
orders.push(x.data());
});
for (order in orders) {
let i = 0;
order.id = id[i];
i++
}
console.log(orders);
}
You should check first, returning snap is either object or array. Generally I found it return object. Hence you should do like.
mounted = async () => {
let id = [];
let orders = [];
db.collection("orders").on("value", async snapshot => {
let ordersData = snapshot.val();
if (ordersData !== null) {
Object.values(ordersData).map(item => {
orders = [...orders, item.data]; //map according to your data
});
}
console.log("orders===>", orders);
});
};

Fetch data from my cloud Firestore and save it to an Object in Node JS

i want to find a way to retrieve my data from my cloud firestore and save it to an object so I can iterate through it, this was my attempt, but I'm sure this might be an array not an object
async function findTrades() {
const ref1 = admin.firestore().collection("bets");
const snapshot = await ref1.get();
const bets = [];
snapshot.forEach(doc => {
bets.push(doc.data());
});
const tokenIds = await Promise.all(results);
return console.log("Here =>" + tokenIds);
}
I want to be able to iterate through it like this
bets.forEach(async match => { console.log(bets.id.name)
});
You can't iterate over an object using a forEach loop. You do need an array for it.
async function findTrades() {
const ref1 = admin.firestore().collection("bets");
const snapshot = await ref1.get();
const bets = {};
snapshot.forEach(doc => {
bets[doc.id] = doc.data();
});
console.log(bets)
}
You can try this code to get something like:
{
"doc1Id": doc1Data,
"doc2Id": doc2Data
}
But as I mentioned above you cannot use a forEach loop on this object. So it's good to have it as an array. Also if you try this code console.log(typeof bets) it'll log object even if it's an array.
Just in case you want it as a key-value pair and still use forEach, you can try this:
Object.keys(bets).forEach((betId) => {
console.log(bets[betId]["name"])
})
Here betId is the document ID and name is just a field in that document.
PS: You can use a for loop as suggested by #Renaud.
doc.data() retrieves all fields in the doc document as an Object: let's call it a "doc Object".
Since you are looping on the results of a Query (to the entire bets collection), instead of pushing the doc Objects to an Array, you could create an object with these doc Objects, as follows.
const bets = {};
snapshot.forEach(doc => {
bets[doc.id] = doc.data();
});
// Then you loop on the Object entries
for (let [key, value] of Object.entries(bets)) {
console.log(`${key}: ${value}`);
}
See these answers for more ways on looping on an Object entries.

How to move all object into an array and send using res.json in node js

Hey guys am trying to loop through an array to get all user data of a particular user using node js and mongodb from another table of information, so each of the element of that array can return a data from the other table. so far if i run my code and console.log it returns all the user data but if i use res.json it returns just 1 data please how do i return all the data using res.json?, can i move all the object into just 1 array if yes please how do i solve it
my code
//get students that offer the course and send link to them
router.get('/send/Link/:id',GetAllUserdata,async(req,res)=>{
const {dept,college,level} = req.body
const responseArray = [];
for (let index = 0; index < res.GetUserDT.coursesHandled.length; index++) {
responseArray.push( res.GetUserDT.coursesHandled[index].courseCode);
}
responseArray.map(async(course,i)=>{
const getActiveClass = await Class.findOne({'school.college':college,'school.department':dept,'school.level':level,'school.course':course,'type':'uploadclass',"expires":0})
if(getActiveClass){
console.log({url:getActiveClass.address,course:getActiveClass.school.course})
}else{
res.status(404).json('nothing')
}
})
})
my console answer
{ url: 'eyaF8Pq6SP8e7YMe48aY', course: 'csc2101' }
{ url: 'c6d8KGfo6WO67QRC0Dq8', course: 'csc2104' }
my res.json answer
{ url: 'eyaF8Pq6SP8e7YMe48aY', course: 'csc2101' }
i'd recommend you to save the results into array and return the array at the end. try to use try catch block to catch the async call errors.
const {dept,college,level} = req.body
const responseArray = [];
let result=[];
for (let index = 0; index < res.GetUserDT.coursesHandled.length; index++) {
responseArray.push( res.GetUserDT.coursesHandled[index].courseCode);
}
try{
responseArray.map(async(course,i)=>{
const getActiveClass = await Class.findOne({'school.college':college,'school.department':dept,'school.level':level,'school.course':course,'type':'uploadclass',"expires":0})
if(getActiveClass){
result.push({url:getActiveClass.address,course:getActiveClass.school.course})
}
})
return res.json(result);
}
catch(error){
res.status(404).json('nothing')
}

How to handle asynchronous axios api call

I'm trying to add a property to the all allIco's object from the tgram array / axios api call. When I add the property using .map its value is undefined. I know it's because my api call is asynchronous but I can't figure out how to add an axios.all...any help would be appreciated :)
var allIcos = Object.assign(ico.results);
let tgram = [];
var result = [];
for (let i = 0; i < allIcos.length; i++) {
axios.get(`url=#${tgramUrl[allIcos[i].name]}`).then(response => {
tgram.push(response.data.result);
}).catch(err => console.log(err));
}
var result = allIcos.map((obj,i) => Object.assign({telegram:"test"}, obj));
this.setState({data: allIcos});
console.log(allIcos);
what about try promise.all?
const promises = [];
for (let i = 0; i < allIcos.length; i++) {
promises.push(axios.get(`url=#${tgramUrl[allIcos[i].name]}`));
}
Promise.all(promises).then(function(values) {
console.log(values);
});
reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
The only way I see is to perform map and setState every time there is a response from the axios call (inside the 'then' clause. Unless you can make one axios call for all (and then, the setState and map should also be inside the 'then', but you know that).

Categories

Resources