Accessing a variable from outside an anonymous function [duplicate] - javascript

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 years ago.
I have a route which performs 2 queries in 2 different databases like so:
app.post('/location',function(req,res){
Db.find({id:anId},function(err,doc){
myDocs=[]
for (var i = doc.length - 1; i >= 0; i--) {
myDocs.push(doc[i])
otherDocs=[]
otherDb.find({id:doc[i].id},function(err,doc2){
for (var i = doc2.length - 1; i >= 0; i--) {
otherDocs.push(doc2[i])
}
})
myDocs.push(otherDocs)
}
res.send(myDocs)
})
})
The issue here is that otherDocs is local to the anonymous function in otherDb, I am not able to access it from outside and push it into myDocs. How would I be able to do this?

You don't have a scoping problem, you have an asynchronous problem. Because the inside of your loop has asynchronous code, you'll have to wait for the callbacks to finish first before pushing them to myDocs and res.sending them.
Easiest solution to this would be to make the function async and then await each inner .find (transformed into a Promise):
app.post('/location',function(req,res){
Db.find({id:anId}, async function(err,doc){
const myDocs = [];
for (const oneDoc of doc.reverse()) {
myDocs.push(oneDoc);
const doc2 = await new Promise(res => {
otherDb.find({id: oneDoc.id}, (err,doc2) => res(doc2));
});
myDocs.push(doc2.reverse());
}
res.send(myDocs);
});
});
Note that this will iterate through each oneDoc's find one-by-one - if you want to send all requests at once rather than in parallel, use Promise.all instead.

Related

Change order in function with fetch [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed last month.
Iam trying to render for Cars from my API. My problem is order in witch this fucntion is called.
export default function getGarage(arrayGarage) {
fetch('http://127.0.0.1:3000/garage')
.then(res => res.json())
.then(res => {
arrayGarage = res
console.log(arrayGarage)
})
if (arrayGarage) {
console.log(arrayGarage)
return arrayGarage
}
}
let arrayGarage = []
arrayGarage = getGarage(arrayGarage)
if (arrayGarage) {
console.log('before while')
for (let i = 0; i < arrayGarage.length; i++) {
console.log('in while')
createCar(arrayGarage[i])
}
}
In first step I got an empty Array (from IF console in fetch), in second step I got "before while" and in third step I got array with my Cars(form then console). How to do that my 'while' wait for property from fetch and handle while.
[]            apiFunctions.js:13
before while         garage.js:43
(4) [{…}, {…}, {…}, {…}]   apiFunctions.js:10

This function keeps returning undefined [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Async Function leaving array blank outside of scope [duplicate]
(4 answers)
Closed 9 months ago.
I have started learning javascript recently and started a new project.
So my problem here is that have this call to an API, everything is good I can access to the names of the pokemons. But when I try to get a return it keep telling me is undefined. I have already try diferents solutions but nothings works.
Console of edge
function arrayOptions(pk) {
fetch('https://pokeapi.co/api/v2/pokemon?limit=10')
.then((res) => res.json())
.then((data) => {
for (let i = 0; i < data.results.length; i++) {
console.log(i, data.results[i].name);
pk.push(data.results[i].name);
}
});
return pk;
}
var pk = [];
pk = arrayOptions(pk);
console.log(pk[0]);

Array has elements on it but its length is zero [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I can't find way to fix this bug, I tried so many things but it's not working, IDK what am I doing wrong.
I have a function which should return array of objects with questions, but it returns array with length 0 so I can't iterate over it. I am using axios to make api call.
I am also bubble sorting the difficulty property inside the array object, so it starts from easy and goes to hard.
let getQuestions = () => {
let questions = [];
axios
.get('https://opentdb.com/api.php?amount=10')
.then((res) => {
for (let i = 1; i < res.data.results.length; i++) {
for (let j = 0; j < res.data.results.length - 1; j++) {
if (
res.data.results[j].difficulty.charCodeAt(3) <
res.data.results[j + 1].difficulty.charCodeAt(3)
) {
const temp = res.data.results[j];
res.data.results[j] = res.data.results[j + 1];
res.data.results[j + 1] = temp;
}
}
}
for (const i in res.data.results) questions.push(res.data.results[i]);
})
.catch((err) => console.error(err));
return questions;
};
console.log(getQuestions());
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
If you are using the returned value then the issue is axios takes time to fetch the data from the API, but in the meantime control moves forward and executes the return statement at which point the value of questions is []. I would suggest using async await syntax instead of then() callback. You simply await for the response from the API and when the response is received the only you return the response from the function.

After a for loop, my variable becomes pseudo array if I don't set a timeout. Why is that? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
To start things off, I'm fairly new to coding and JS, so maybe I'm misunderstanding something very basic here.
I built a script to check a .JSON file for any fields named "ID: XXXX". Its purpose is to return every article's unique identifier from a blog. The unique identifier is "XXXX" in this case.
The script does what it's supposed to, but when I return the values to my global variable article_identifiers, they're returned as a pseudo array. I can't access single values by indexing them via article_identifiers[i].
However, when I set a timeout, article_identifiers is returned as a normal array and I can access the values inside the array by using console.log(article_identifiers[i]).
Here's the code, for context:
var article_identifiers = [];
var url = '/articles.json';
fetch(url)
.then((response) => response.json())
.then(data => {
var article_amount = Object.keys(data.articles).length;
for (var i = 0; i < article_amount; i++) {
article_identifiers.push(data.articles[i].id);
}
})
setTimeout(function(){
console.log(article_identifiers);
},500);
Why do I have to set a timeout? Am I misunderstanding something about the way JavaScript code is processed? Does my console.log() fire before my for loop is finished? If so, why?
First off, thanks for the super fast replies!
Here's the solution:
var article_identifiers = [];
var url = '/articles.json';
await fetch(url)
.then((resp) => resp.json())
.then(data => {
var article_amount = Object.keys(data.articles).length;
for (var i = 0; i < article_amount; i++) {
article_identifiers.push(data.articles[i].id);
}
})
console.log(article_identifiers);
fetch() is an asynchronous function, so I just had to put an await before that.
I'll mark this one as a lesson to always check if a prebuilt function is async or not.
Thanks!

How to use an array which is returned from 1 function in Nodejs? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
I have 1 function in Nodejs that return a list of recipient:
var recipientList = [];
userService.listUser().then( result => {
var listPSID = result.filter(result => !'279'.includes(result));
recipientList = listPSID.slice();
console.log(recipientList);
});
Now I want to access that list OUTSIDE the function, something likes:
console.log(recipientList[0]);
How can I do that? Thank you all.
If you're using Promises, you cannot access it outside the function. If you use async / await instead, it should work.
async function getList(){
let result = await userService.listUser();
var listPSID = result.filter(result => !'279'.includes(result));
recipientList = listPSID.slice();
console.log(recipientList[0]);
}

Categories