This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed last year.
let found = false;
axios
.get(link)
.then((response) => {
response.data.map((element) => {
if (element.id_ticket.toString() === nbTicket) found = true;
});
console.log(found);
});
so im trying to get data from the api and see if the value of 'nbTicket' is in the returned data and that is done using the 'found' variable so if i log the 'found' variable value outside the .then method it stays false even if the value exists and when i do it iside the .then methods it gives the correct value
let found = false;
axios
.get(link)
.then((response) => {
response.data.map((element) => {
if (element.id_ticket.toString() === nbTicket) found = true;
});
});
console.log(found);
Your supposed to use async/await strategy, because console.log happens after Axios request:
async function getNbTicket(){
let found = false;
const { data } = await axios.get(link);
data.data.map((element) => {
if (element.id_ticket.toString() === nbTicket) found = true;
});
return found;
}
your console.log(found); is executing is executing before you fetch data from api
you can call it inside then or use async await if you want to call console.log(found); after you get data from api
This is normal behavior, because of the async and sync.
you have two options
first one is to wrap your code inside a async function
const checkIfTicketIsFound = async () => {
let found = false;
const { data } = await axios.get(link);
data.map((element) => {
if (element.id_ticket.toString() === nbTicket) found = true;
})
console.log(found)
return found
}
Or
you need to print inside the then chain
let found = false;
axios
.get(link)
.then((response) => {
response.data.map((element) => {
if (element.id_ticket.toString() === nbTicket) found = true;
});
console.log(found);
});
Related
This question already has answers here:
Using async/await with a forEach loop
(33 answers)
Closed 2 years ago.
async onclick(){
let number=this.state.phoneNumber
if(number !== null && number.length===10){
console.log('number',number)
await firestore().collection('profile')
.where('mobile', '==', number).get().then(snapshot => {
if (snapshot.empty) {
}
else{
console.log(snapshot.data())
const res=Promise.resolve(async function(){
let data=[]
await snapshot.forEach(doc => {
data.push({data:doc.data().uid})
})
return data
})
if(res.length !==0){
res.then((pra)=>{
let payload={Requester:auth().currentUser.uid,Responder:pra}
firestore().collection('requests').add(payload).then(function() {
goHome();
});
})
}
}
})
}
else{
showSnackbar('Please enter valid mobile number');
}
}
this is the my code here here i want to wait for foreach to complete the after this is want to save the data received from the this foreach to firebase but issue is that before the foreach finish it is running the quert so i am getting null data in firebase
The issue is not async/await, your res is a Promise, and the length will always be undefined. For example:
var p = Promise.resolve([1,2,3]);
console.log(p.length) // undefined
Could you try with this correction?
const res = await Promise.all( snapshot.map( doc => doc.data().uid ) );
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I am very new to JavaScript, trying to understand the concepts of asynchronous function. So, basically I wrote a webScraper for RateMyProfessor using nightmare. This is the function:
var Nightmare = require("nightmare"),
nightmare = Nightmare();
const baseURL =
"https://www.ratemyprofessors.com/search.jsp?queryBy=schoolId&schoolName=University+of+California+Santa+Barbara&schoolID=1077&queryoption=TEACHER";
const getRatingProfessor = (professorName) => {
let rating;
let nameSplitter = professorName.split(" ");
if (nameSplitter.length > 2) {
professorName = nameSplitter[0] + " " + nameSplitter[1];
}
nightmare
.goto(baseURL)
.click("#ccpa-footer > .close-this")
.type("#professor-name", professorName)
.wait(1000)
.evaluate(() => {
var resultList = document.querySelectorAll("a .rating");
//if no result is found
if (typeof resultList === "undefined" || resultList.length == 0) {
return "Not Found";
}
//Found the professor with exact name
if (resultList.length == 1) {
return document.querySelector("a > .rating").innerHTML;
}
//conficting similar professor names (rare case)
if (resultList.length >= 2) {
return "Cannot Determine";
}
})
.end()
.catch((err) => {
console.log(err);
})
.then((text) => {
rating = text;
console.log(professorName, text);
});
return rating;
};
console.log(getRatingProfessor("XXXXX"));
If I run this program, it gives the following output:
undefined
SomeProfName 4.8
It seems like the function returned the rating to console.log without waiting for the promise. Why isn't function not waiting for the nightmare promise to get resolved. More importantly, why isn't the value of rating getting updated; or it has been updated but console.log doesn't want to wait for the function?
Sorry, these questions may look absurd, but I would really appreciated the answers :0
Your function explicitly does not return anything hence will return undefined by default. What you are getting is correct but within the then()...
If you wanted to return an async result you'd need to declare your function as async and then await the result.
const getRatingProfessor = async (professorName) => {
let rating;
let nameSplitter = professorName.split(" ");
if (nameSplitter.length > 2) {
professorName = nameSplitter[0] + " " + nameSplitter[1];
}
await text = nightmare...
return text;
};
(async () => {
console.log(await getRatingProfessor("XXXXX"));
}
)()
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I tried to fetch some information through a API and it worked. The next step was to define "ourserver" with the right server data. So I made a foreach and I console-logged just server and got the right one, but if I try to define ourserver = server; the last console log is showing me that ourserver is still undefined.
let ip = "myserverip";
let ourserver;
const fetchPromise = fetch('http://myapi.com/list/servers')
fetchPromise.then(response => {
return response.json();
}).then(list => {
list.forEach(function (server) {
if (server.host === ip) {
ourserver = server;
// console.log(server); this was defined
}
});
});
console.log("daten: " + ourserver); // this is after all still undefined
The reason you are seeing this issue is because your code to define ourserver actually occurs after your console.log("daten: " + ourserver);, you can prove this to yourself by logging the date, too:
ourserver = server;
console.log(server, new Date());
...
console.log("daten: " + ourserver,new Date());
You will see the daten console.log occurs before your log of server.
When you call fetch, it will perform the fetching in the background, and once it has completed, it will call the function provided to then. This is how asynchronous programming works in JavaScript.
Your code that requires ourserver to be present should happen in your then.
Here's your code modified to show how I would go about this:
const ip = "myserverip";
fetch('http://myapi.com/list/servers').then(response => {
return response.json();
}).then(list => {
return list.find(server => server.host === ip);
}).then(ourserver => {
console.log("daten: " + ourserver);
});
If you absolutely must access the value of ourserver outside of the fetch, this can be achieved one of two ways. One way is to define a callback, and the other way is to wait for the value to be set. Here are both ways:
callback
const ip = "myserverip";
let ourserver = null;
const callback = () => {
console.log(ourserver);
}
fetch('http://myapi.com/list/servers').then(response => {
return response.json();
}).then(list => {
ourserver = list.find(server => server.host === ip);
callback();
});
wait
const ip = "myserverip";
let ourserver = null;
fetch('http://myapi.com/list/servers').then(response => {
return response.json();
}).then(list => {
ourserver = list.find(server => server.host === ip);
});
const check = () => {
if(ourserver == null){
return setTimeout(check,100);
}
console.log(ourserver);
};
check();
I do not recommend using the wait and check solution.
read more about Async JS and promise, the reason for this that
fetch promise will run
it's an async operation so the interpreter will not wait until it finish so he will continue execution for the rest of the file.
it will print the console.log
and if the async operation finished the call back will be put in something called event queue, and if the call stack is empty, the event loop will execute your callback function which be the function inside .then in your case.
let ip = "myserverip";
let ourserver;
async function fetchPromise(){
try{
const response = await fetch('http://myapi.com/list/servers');
const list = await response.json();
list.forEach((server) => {
if (server.host === ip) {
ourserver = server;
}
});
console.log("daten: " + ourserver);
}catch(e){
console.log(e);
}
}
You can make use of async/await to handle the fetch better and for a cleaner code. This way you gonna wait until you get the response from the fetch api and then you will have the value of ourserver available.
This question already has answers here:
Avoiding callback hell in promises using nodejs
(2 answers)
Closed 3 years ago.
I'm having a hard time to sequence my API calls. so I used then() chaining to sequence them in order. All the API and the refresh token are Promises/Async. It's working but is there a cleaner/fancier/shorter way to this without using async/await because my parent function is not async. I don't fully understand the behavior of .then() and async/await
Here is the code inside the parent function:
refreshToken().then(token => {
let request = {} //format request
return axios.post(`${youtubeUrl}/upload/youtube/v3/videos?access_token=${token}&part=contentDetails`, request) //upload video
})
.then(uploadResponse => {
let uploadResponse = {}; //format uploadResponse
refreshToken().then(token => { //refresh the token again
return axios.put(`${youtubeUrl}?access_token=${token}`, uploadResponse) //update existing video
})
.then(updateResponse => {
let updateResponse = {}; //format updateResponse
axios.post(`${BasePath}/v1/videos`, updateResponse, headers)
.then(postResponse => {
if (postResponse.data.response === 'success') {
return dispatch(receivePostsData(postResponse.data))
} else if (postResponse.data.response === 'failed') return dispatch(receivePostsData(postResponse.data))
})
})
})
.catch(error => {
return dispatch(receivePostsData(error))
})
With aysnc await you can convert your callback hell to this:
important notes are:
async keyword before the function allows to use await
To handle exceptions you need to use try catch block.
async function uploadToYoutube() {
try {
let token = await refreshToken();
let request = {}
const youtubeUploadResponse = await axios.post(`${youtubeUrl}/upload/youtube/v3/videos?access_token=${token}&part=contentDetails`, request);
let uploadResponse = {};
token = await refreshToken();
const youtubeUpdateResponse = await axios.put(`${youtubeUrl}?access_token=${token}`, uploadResponse);
let updateResponse = {};
let postResponse = await axios.post(`${BasePath}/v1/videos`, updateResponse, headers);
if (postResponse.data.response === 'success') {
return dispatch(receivePostsData(postResponse.data))
} else if (postResponse.data.response === 'failed') {
//??? why do you here act like a success?
return dispatch(receivePostsData(postResponse.data))
}
} catch (error) {
//??? why do you here act like a success?
return dispatch(receivePostsData(error))
}
}
If you are using ES6 and above you can use async await
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 5 years ago.
I have this promise:
var seasonalityArray;
...
aService.gettingAnalysis(site, cohortKey)
.then(function (result) {
let date = moment();
seasonalityArray = result.cooling.getSeasonMonths(date);
})
, function (error) {
console.error('An error occurred', error);
};
const totalAccounts = _.size(report.asModel().accountNumbers);
const warnings = _.compact(_.map(seasonalityArray, function (monthLabel) {
...
}));
...
aService.gettingAnalysis = function (site, Key) {
return Promise.all([
aService.findingHeat(site, Key),
aService.findingCool(site, Key)
]).spread(function (heating, cooling) {
return { heating: heating, cooling: cooling };
});
};
Inside seasonalityArray variable, it must get an array of months (e.g. ['June','July','August']) which will be used afterwards.
The problem that I found while debugging each step is that after it goes in the line with aService.gettingAnalysis it doesn't enter in .then() and all the code after but it jumps to setting totalAccounts and afterwards it enters in warnings with seasonalityArray being undefined.
Is there a way to make it enter inside then() or at least to set that variable before it is using it as undefined?
aService.gettingAnalysis(site, cohortKey)
.then(function (result) {
let date = moment();
seasonalityArray = result.cooling.getSeasonMonths(date);
//now we can do the rest
const totalAccounts = _.size(report.asModel().accountNumbers);
const warnings = _.compact(_.map(seasonalityArray, function (monthLabel) {}));
})
, function (error) {
console.error('An error occurred', error);
};
Possible duplicate of how to return from an asynchronous call, so you may read a bit more about Promises.
A Promise is not meant to execute right now, but somewhen. So you cannot simply put code behind it and expect it to execute after the Promise has finished. And you may have a look at async && await ...
If you need the data to be there when you use it you have to use it after your promise resolves.You can move the work you need to be done to a
function.
var seasonalityArray;
...
aService.gettingAnalysis(site, cohortKey)
.then(function(result) {
let date = moment();
seasonalityArray = result.cooling.getSeasonMonths(date);
doStuff();
})
function doStuff() {
const totalAccounts = _.size(report.asModel().accountNumbers);
const warnings = _.compact(_.map(seasonalityArray, function(monthLabel) {
...
}));
}
I'd do away with the "global" and chain promises instead.
aService.gettingAnalysis(site, cohortKey)
.then(function(result) {
let date = moment();
seasonalityArray = result.cooling.getSeasonMonths(date);
return seasonalityArray;
}).then(doStuff)
function doStuff(seasonalityArray) {
const totalAccounts = _.size(report.asModel().accountNumbers);
const warnings = _.compact(_.map(seasonalityArray, function(monthLabel) {
...
}));
}
then returns a promise where the data that get's resolved is what the then returns.