I'm making a function to return a boolean to know if an element is present or not, but I get
this is the status: false
How can I get an only true or false response, please help, I'm using an if condition but it shows that response...
async IsPresent(element){
try{
await element.isPresent().then(function(status){
console.log("this is the status: " + status);
return status;
});
}
catch(err){
return console.log(err);
}
};
this is the function where I'm calling IsPresent
async ClickSomething(){
try{
await this.helpers.ClickElement(oneElement);
if(await this.helpers.IsPresent(anotherElement) == false){
//Do something
}else{
//Do something esle
}
catch(err){
return console.log(err);
}
};
There is a lot of unnecessary code in that function. You could achieve the same functionality using the following
async IsPresent(element){
try {
return await element.isPresent();
}
catch (err) {
return console.log(err);
}
};
First thing to note is that when a function is declared async you are able to use the await keyword to pause the execution until that any associated promise is resolved. You are actually using two different approached to resolve promises here (promise.resolve and .then()) when only awaits are necessary.
Second thing to note is that isPresent return true or false anyway so that can be directly returned from your function.
Related
I currently have a problem with my function. I'm using a MongoDB Database to check is something exists and as you can see, if a data value is true, I wanna set the return value of the function to false or when it's wrong it should return false.
Everything works to this point.
The function is just returning "undefined". I tried everything I could think of and tested atleast one hour but couldn't find any solution.
I hope anyone of you guys could help me to return a true or false here.
Thanks for your help :D
Note: Also tried it with async before, didn't work out
function CheckActiveGamesPlayer1(memberid) {
console.log("3")
db.findOne({ GuildID: guild.id, Player1: memberid }, async(err, data) => {
if (data.Ingame === true) {
console.log("4")
Embed.setDescription(`<#${memberid}> is in an active game. Can't start the game!`).setColor("RANDOM");
channel.send({ embeds: [Embed], ephemeral: true })
return false;
} else {
console.log("5")
return true;
}
})
}
That is because you aren't actually returning anything in CheckActiveGamesPlayer1. However, you are returning something in your db.findOne callback.
I am not sure how you are calling the CheckActiveGamesPlayer1 function, but I would suggest returning a Promise so you can either await or .then it to get the response you're after.
function CheckActiveGamesPlayer1(memberid) {
console.log('3');
return new Promise( (resolve, reject) => {
db.findOne({ GuildID: guild.id, Player1: memberid }, async (err, data) => {
if (data.Ingame === true) {
console.log('4');
Embed.setDescription(`<#${memberid}> is in an active game. Can't start the game!`).setColor('RANDOM');
channel.send({ embeds: [Embed], ephemeral: true });
resolve(false);
} else {
console.log('5');
resolve(true);
}
});
});
}
You can then call your function and get the response by .then
IE:
CheckActiveGamesPlayers1(1).then( result => console.log(result) );
You can also add async to your CheckActivePlayers1 function so you can just await it.
IE:
async function CheckActiveGamesPlayer1(memberid) { ... }
const result = await CheckActiveGamesPlayers1(1);
I am not sure which version of mongo you are working with. But there's a chance you can just return db.findOne as long as that returns a promise. The way you are currently using db.findOne is in the form of a callback, so there would be some code re-arranging if you went this route.
https://www.mongodb.com/docs/drivers/node/current/usage-examples/findOne/
Try something like this. db.findOne probably returns a promise, so you can do await db.findOne instead of providing a callback, then you can return like normal after that.
async function CheckActiveGamesPlayer1(memberid) {
console.log("3")
const data = await db.findOne({ GuildID: guild.id, Player1: memberid });
if (data.Ingame === true) {
console.log("4")
Embed.setDescription(`<#${memberid}> is in an active game. Can't start the game!`).setColor("RANDOM");
channel.send({ embeds: [Embed], ephemeral: true })
return false;
} else {
console.log("5")
return true;
}
}
This is not an async function. Your function runs first, returns with undefined.
Then, the async callback is called but that value is passed to nothing.
One way to fix this is to make this an async function, then use "await" keyword.
Coming from Jquery $.get, I am trying to rewrite a function that gets data in a json. So far, this is what I do:
async function get_highlights(){
const mirespuesta = await fetch("/api/v1/gethighlights/"+network_number)
.then(response => {
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.json();
})
.then(json => {
console.log(json) // --> here, I get the correct dara
return json;
})
.catch(function () {
this.dataError = true;
})
return mirespuesta
} // but I don't get that data returned
But I just get this when I call the fuction:
that has the values, but I can't get them returned or used on the main scope of my application.
What am I doing wrong?
The problem is that you never return the promise chain from your function. So your async function's return value is a promise fulfilled with undefined, just like a non-async function with no return returns undefined.
There's another issue with that code: If you're using an async function, generally it's best to use await rather than .then, .catch, etc. Also, don't catch rejection in the function; instead, let the caller handle it so it knows something went wrong.
So for instance:
async function get_highlights() {
const response = await fetch("/api/v1/gethighlights/"+network_number);
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
return response.json();
}
But if you really want to handle errors inline:
async function get_highlights() {
const response = await fetch("/api/v1/gethighlights/"+network_number);
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
try {
return await response.json();
} catch { // Note: ES2019 allows optional `catch` bindings
this.dataError = true;
}
}
but again I don't recommend that, because the caller has to check to see whether they got data or undefined when the promise is fulfilled (or check dataError, I guess :-) ).
Side note: Note that in the first example, which doesn't have a try/catch, I did return response.json(); but in the second example, where the return is inside a try/catch, I did return await respohnse.json();. The reason is that when returning a promise at the top level of the function, there's no effective difference between return somePromise and return await somePromise, but that's not true if the code is in a control block like a try/catch. Having the await ensures that our catch block is executed if the promise is rejected. Not having it wouldn't ensure that.
This is what your function should look like:
async function get_highlights() {
const mirespuesta = await fetch("/api/v1/gethighlights/"+network_number);
if (!mirespuesta.ok) {
throw new Error("HTTP error " + mirespuesta.status);
}
return mirespuesta.json();
}
But, most importantly this is how it should be used:
const mydata = await get_highlights();
An async function ALWAYS returns a promise, and your question probably becomes a dupe of this question
Another way would be to use just await twice
try {
const mirespuesta = await (await fetch("/api/v1/gethighlights/"+network_number)).json();
} catch {
throw new Error(response.status);
}
return mirespuesta;
I am writing Unit Testing which require me to hit the exceptions. Incase of promises, I cannot really send any boolean or string values. My intended output and the one I am getting is mentioned below.
function mainFunction(registry, name,....){
justAnotherPromiseFunction(name, function (err, twin) {
if (err) {
return "I want to return a failure message here!";
} else {
<MyLogic Goes Here>
}
});
}
console.log(mainFunction(registry, name,....));
This returns Promise { <rejected> [ArgumentError: The connection string is missing the property: Something] }.
Instead of I want to return a failure message here!.
Any ideas on how I can manage to do this?
Edit: I am implementing a function from azure sdk that uses promises.
So looks like this:
function mainFunction(){
registry.getTwin(name, function (err, twin) {
if (err) {
return "I want to return a failure message here!";
} else {
<My Business Logic Goes Here>
}
});
}
console.log(mainFunction());
You are using it in the wrong way. You cannot print the result of promise just by callint it. A promise return its result in the then function.
Please see following examples.
async function mainFunction() {
try {
const result = await myPromise();
return result;
}
catch (err) {
return 'I want to return a failure message here!'
}
}
function myPromise() {
return new Promise(function(resolve, reject) {
})
}
it("test async function", async() => {
console.log(await mainFunction())
})
Make your test function async so you can await for the result.
I have an async function that posts data to Firebase Firestore. It works, apart from I need it to do some things after the data has been posted, or 'on success'.
In the code below I'm trying to 'setLoading' to false after the data has been posted to Firestore. The data does get posted, but the loading value remains true. Can anyone see what is wrong with my code, please? I want to do some other things apart from change the value of 'loading', but I'm just using this one instance as an example here.
async function uploadData(e) {
e.preventDefault()
try {
setLoading(true)
return await useFireStore
...
}
catch {
setError('Post failed')
}
setLoading(false) // this isn't working
}
Cheers, Matt
If you want something to happen on success, you just place is below your await. If you want it to happen no matter what, you can use the finally block.
try {
setLoading(true)
const result = await useFireStore;
// logic here to run on success
return result;
}
catch {
setError('Post failed')
}
finally{
// logic here to always run
setLoading(false);
}
The issue is that you're using return in your try catch. This is no different from when you're using try/catch and return in a non-async function. (By design.)
Typically you'd use finally for this:
async function uploadData(e) {
e.preventDefault()
try {
setLoading(true)
return await useFireStore/*...*/;
}
catch {
setError('Post failed')
}
finally {
setLoading(false) // this isn't working
}
}
Note that the await in the above is important. There's no need for return await somePromise if it's at the top level of your function code (just use return somePromise), but the await can make a big difference if it's not at the top level, which is the case here. So you do need that await.
Side note: As written, your function fulfills its promise with the result of the useFireStore call if it works, but with undefined if it doesn't work. If useFireStore can return undefined, that means code using your function has no idea whether the operation succeeded or failed. (But if useFireStore doesn't every return undefined on success, then code using your function could tell the difference.)
You used return inside try block so it is returning without setting the loading status to false. Also, you should set the loading status to false on error case as well, so your code should look like:
async function uploadData(e) {
e.preventDefault()
setLoading(true)
try {
await useFireStore
}
catch {
setError('Post failed')
}
finally {
setLoading(false)
}
}
You're returning after the request is created, if you need to use the response, store it in the variable instead of returning, also if you want to make sure any code is executed after the request was completed ( successful or unsuccessful), use the finally block
async function uploadData(e) {
e.preventDefault()
try {
setLoading(true)
const response = await useFireStore(); // don't return here
// use the response var if it request returns any data
} catch {
setError('Post failed')
} finally {
setLoading(false) //move the setLoading here
}
}
I'm trying to get the hang of using Mongoose promises with the async/await functionality of Node.js. When my function printEmployees is called I want to save the list of employees which are queried by the orderEmployees function. While, the console.log statement inside orderEmployees returns the expected query, the console.log inside of printEmployees returns undefined, suggesting that I'm not returning the promise correctly.
I'm new to promises so entirely possible that I'm not correctly understanding the paradigm... any help is much appreciated.
printEmployees: async(company) => {
var employees = await self.orderEmployees(company);
// SECOND CONSOLE.LOG
console.log(employees);
},
orderEmployees: (companyID) => {
User.find({company:companyID})
.exec()
.then((employees) => {
// FIRST CONSOLE.LOG
console.log(employees);
return employees;
})
.catch((err) => {
return 'error occured';
});
},
In order to make orderEmployees behave like async functions, you have to return the resulting promise. There are two rules to follow when using promises without async/await keywords:
A function is asynchronous if it returns a Promise
If you have a promise (for example returned by an async function) you must either call .then on it or return it.
When you are using async/await then you must await on promises you obtain.
This said you will notice that you do not return the promise generated inside orderEmployees. Easy to fix, but its also easy to rewrite that function to async too.
orderEmployees: (companyID) => {
return User.find({company:companyID}) // Notice the return here
.exec()
.then((employees) => {
// FIRST CONSOLE.LOG
console.log(employees);
return employees;
})
.catch((err) => {
return 'error occured';
});
},
or
orderEmployees: async(companyID) => {
try {
const employees = await User.find({company:companyID}).exec();
console.log(employees);
return employees;
} catch (err) {
return 'error occured';
}
},
PS: the error handling is somewhat flawed here. We usually do not handle errors by returning an error string from a function. It is better to have the error propagate in this case, and handle it from some top-level, UI code.
You need to return your Promise.
Currently, you are awaiting on a function that returns undefined.
await only actually "waits" for the value if it's used with a Promise.
Always keep in mind that you can only await Promises or async functions, which implicitly return a Promise1.
orderEmployees: (companyID) => {
return User.find({ company:companyID }).exec()
}
Also really important, you should throw instead of return in your .catch handler. Returning from within a .catch handler will cause the promise chain to trigger it's .then instead of it's .catch thus breaking the error handling chain.
Better yet, don't include .catch at all and let the the actual error bubble up the promise chain, instead of overriding it with your own non-descriptive 'error occured' message.
Error conditions should throw the error, not return it.
1 You can also await non-Promises, but only for values that are evaluated synchronously.
You are not returning a Promise from orderEmployees.
printEmployees: async(company) => {
var employees = await self.orderEmployees(company);
// SECOND CONSOLE.LOG
console.log(employees);
},
orderEmployees: (companyID) => {
return User.find({company:companyID})
.exec()
.then((employees) => {
// FIRST CONSOLE.LOG
console.log(employees);
return employees;
})
.catch((err) => {
return 'error occured';
});
},
You need to return a Promise from orderEmployees
orderEmployees: companyId => User.find({ companyId }).exec()
If you want to do some error handling or pre-processing before you return then you can keep your code as is but just remember to return the result (promises are chainable).
if you're going to use async/await then it works like this.
await in front of the function that returns a promise.
async in front of the wrapping function.
wrap the function body inside try/catch block.
Please have a look on this function, it is a middleware
before i execute a specific route in express.
const validateUserInDB = async (req, res, next) => {
try {
const user = await UserModel.findById(req.user._id);
if (!user) return res.status(401).json({ message: "Unauthorized." });
req.user = user;
return next();
} catch (error) {
return res.status(500).json({ message: "Internal server error." })
}
}
The code after await is waiting the promise to be resolved.
Catch block catches any error happened inside the try block even if the error that is triggered by catch method comes from awaiting promise.