How to seperate function with await - javascript

I just switch from php into full time js. I try to clean code in javascript function but still confuse how to deal with it
for(let i in allEmpData) {
let emp = allEmpData[i]
if(empData == null) {
const addEmp = new Employee()
this.addEmpFn(addEmp, emp)
}
if(empData != null) {
this.addEmpFn(empData, emp)
}
}
I call function addEmpFn because I put create/update code in thier here is my function addEmpFn
addEmpFn(empData, emp) {
empData.name = emp.name
return await empData.save()
}
the error said :
Unexpected token return await
I want to do something like this but In the clean code , seperate function
for(let i in allEmpData) {
const empData = await Employee.query()
.where('id',1)
.first();
let emp = allEmpData[i]
if(empData == null) {
const addEmp = new Employee()
addEmp.name = emp.name
return await empData.save()
}
if(empData != null) {
empData.name = emp.name
return await empData.save()
}
}

You need to assign function as async as follows:
async addEmpFn(empData, emp) {
empData.name = emp.name
return await empData.save()
}

await keyword only works inside async functions. so you have to write async keyword before function declaration.
like this;
async addEmpFn(empData, emp) {
empData.name = emp.name
return await empData.save()
}

You don't really need an async await here, async await is needed when you want to wait for the promise to get resolved.
And also return await is an anti-pattern in JS until you don't want to use try-catch around.
Following code is the way to go, works same as the accepted answer.
addEmpFn(empData, emp) {
empData.name = emp.name
return empData.save()
}

Try to mention async before your funtion like below I mentioned
async addEmpFn(empData, emp) {
empData.name = emp.name;
return await empData.save();
}

Related

How to only execute a function once in Javascript?

I have an if else statement in my main function, when the if statement is true I want to continue another function inside the if statement.
However the if statement stays true until a transaction is confirmed, which leads to retrigger the 2nd function to be executed more than once.
The buyToken function gets executed inside the if statement of the mempool function
async function buyToken(){
try{
const value = '1000000000000000'
const amountOut = await routerContract.getAmountsOut(value,[wbnb, tokenToFrontRun] )
console.log(ethers.utils.formatEther(amountOut[0]))
console.log(ethers.utils.formatUnits(amountOut[1], 9))
const buy = await routerContract.swapExactETHForTokensSupportingFeeOnTransferTokens(
0,
[wbnb, tokenToFrontRun],
address,
Date.now() + 1000 *60*3,
{
'value':value,
'gasPrice':ethers.utils.parseUnits('80', 'gwei'),
'gasLimit':300000
}
)
receipt = await buy.wait()
console.log(receipt.transactionHash)
return
}catch(e){
console.log(e)
}
}
async function mempool(){
provider.on("pending", async(tx)=>{
const txInfo = await provider.getTransaction(tx);
try{
//console.log(txInfo.to)
if(toChecksumAddress(txInfo.to) == routerAddress){
console.log("to uniswap router")
const iface = new ethers.utils.Interface(routerAbi);
let decodedData = iface.parseTransaction({ data: txInfo.data});
const valueSent = ethers.utils.formatUnits(txInfo.value, 'ether')
const first = decodedData.args.path[0]
const lastItem = decodedData.args.path
const last = lastItem[lastItem.length -1]
if(toChecksumAddress(first) == wbnb && toChecksumAddress(last) == tokenToFrontRun ){
console.log(txInfo);
console.log(ethers.utils.formatEther(txInfo.value))
console.log(ethers.utils.formatUnits(txInfo.gasPrice, 'gwei'))
// console.log(ethers.utils.formatUnits(txInfo.gasLimit, 'gwei'))
console.log(txInfo.confirmations)
console.log(txInfo.from)
console.log("front running transaction")
await buyToken()
}
}
}
catch (e){
//console.log("no data to show");
//console.log(e)
}
})
}
mempool()
So how can I make it so that the buyToken function is only executed once?
I know there are plenty of tutorials on w3schools, but this doesn't really help me in this case.
Define the buyToken function as an arrow function.
let buyToken = async () => {
// your logic
}
Then in the event,
if (buyToken)
await buyToken();
buyToken = null;
But, in ethers.js instead of using on, you can use once to call the method once.
So, in your case,
provider.once("pending", async(tx)=>{
// your logic
})

Async Function Promise (axios)

I am trying to fetch the gas prices from ethgasstaion and work with this value in the global scope. Is there a way that I can include a global variable in my .then() part and assign the value of my async function to that variable?
I get the right value but can't assign it to the global variable.
// Eth Gas Station
let fast_value = 0;
async function getCurrentGasPrices() {
let response = await axios.get(process.env.ETH_GAS_Station_API)
let price = {
fast: response.data.fast
}
return price
}
getCurrentGasPrices().then(value => {
fast_value += value.fast;
})
console.log(fast_value)
Appreciate the help!
You can wrap everything into an immediately invoked async function, so we can use await inside:
(async () => {
let fast_value = 0;
async function getCurrentGasPrices() {
let response = await axios.get(process.env.ETH_GAS_Station_API);
let price = {
fast: response.data,
};
return price;
}
let response = await getCurrentGasPrices();
fast_value = response.fast;
console.log(fast_value);
})();

How to compare the value resulting from two promises in Javascript?

async function getDNShomeIP(){
var response = await fetch('https://dns.google/resolve?name=example.com'); // this uses the google api
var json = await response.json();
var homeIPadress = json.Answer[0].data;
console.log(homeIPadress);
return homeIPadress;
};
async function getCurrentIP(){
var response = await fetch("https://api.ipify.org?format=json");
var json = await response.json()
var currentIPadress = json.ip;
return currentIPadress;
}
var homeIPadress = getDNShomeIP();
var currentIPadress = getCurrentIP();
if (homeIPadress == currentIPadress){
alert("from same from lol");
} else {
alert("not from same")
};
Hi there,
I wanted to know how to compare the values of two promises in Javascript.
I can't work out how to make the program wait before the if statement.
The statement just evaluates to false if the promises are not yet fulfilled so program follows the else branch.
Thanks
Use the "await" keyword inside another "async" function so that the function waits for a response before it continues execution.
async function testEquality() {
var homeIPadress = await getDNShomeIP();
var currentIPadress = await getCurrentIP();
if (homeIPadress === currentIPadress) {
alert("from same from lol");
} else {
alert("not from same")
};
}
testEquality();
I would also recommend you use triple equal (===) to compare the results as this uses strict equality comparison.
You could wrap it in another async function:
async function execute() {
var homeIPadress = await getDNShomeIP();
var currentIPadress = await getCurrentIP();
if (homeIPadress == currentIPadress){
alert("from same from lol");
} else {
alert("not from same");
}
}
execute();
first you need to fix your fetch function, then fix the async await function
you have to put your await function on async function just like this,
fix your getdnshomeip just like the code below
function getCurrentIP(){
return fetch("https://api.ipify.org?format=json")
.then( r => r.json())
.then( r => r);
}
const check = async () => {
var currentIPadress = await getCurrentIP();
var homeIPadress = await getDNShomeIP();
if (homeIPadress === currentIPadress){
alert("from same from lol");
} else {
alert("not from same")
};
}
check();
You're describing a function I created
async function getDNShomeIP(){
var response = await fetch('https://dns.google/resolve?name=example.com');
var json = await response.json();
var homeIPadress = json.Answer[0].data;
console.log(homeIPadress);
return homeIPadress;
};
async function getCurrentIP(){
var response = await fetch("https://api.ipify.org?format=json");
var json = await response.json()
var currentIPadress = json.ip;
console.log(currentIPadress);
return currentIPadress;
}
const { eq } = rubico
eq(getDNShomeIP, getCurrentIP)().then(console.log)
<script src="https://unpkg.com/rubico/index.js"></script>
documentation for eq

Handling Async Function

I have the following function:
export function readUserData(userName, password) {
firebase.database().ref("users/" + userName).once("value").then(function (snap) {
//console.log(snap.val().salt);
var verification = passwordVerify(password, snap.val().salt);
//console.log(verification);
//console.log(snap.val().password);
console.log(snap.val());
return snap.exists() && snap.val().password === verification
? userAuth.located = snap.val()
: userAuth.located = false;
});
return userAuth.located;
}
I am told that firebase.database().ref is an asynchronous function, and it seems to be so in that it returns userAuth.located in the final line of readUserData before writing console.log(snap.val());
How do I ensure that firebase.database().ref... executes before I return the final result? I am unsure how to implement await/promises into this code as the overall function is not asynchronous.
You should return the promise, like:
export function readUserData(userName, password) {
return firebase.database().ref("users/" + userName)
.once("value")
.then(function (snap) {
var verification = passwordVerify(password, snap.val().salt);
return snap.exists() && snap.val().password === verification
? snap.val()
: false;
});
}
Then, whichever code calls this method, should also async-await:
var userAuthLocated = await readUserData(userName, password);
or, with promises:
readUserData(userName, password)
.then(userAuthLocated => {
// use userAuthLocated here
});
To address your comment above #Seaphin. There is one more step needed with the following line
var userAuthLocated = await readUserData(userName, password);
What is happening is that your app is using userAuthLocated before it updates. userAuthLocated does get updated by the firebase call in readUserData, however, you are missing an async() function.
Using await should always be wrapped in an async () function call. It should look something similar to this
userAuth = async () => {
var userAuthLocated = await readUserData(userName, password);
//setstate or
return userAuthLocated
Essentially using async "blocks" until the value is ready to use. Functions waiting on that value won't execute until the async function unblocks

How can I access and use a return value from a do while loop?

I am trying to access return data from a do while loop, but I am unable to do so.
I have stored the information in a new variable (starships) and then returned this variable, but it says starships is not defined. I see that this may be a scoping issue, how can I resolve this?
async function getData() {
const allResults = [];
let url = 'https://swapi.co/api/starships/';
do {
const res = await fetch(url);
const data = await res.json();
url = data.next;
allResults.push(...data.results);
console.log(allResults);
} while (url !== null)
let starships = allResults;
return starships;
}
console.log(starships);
You need to get the value which is returned from getData. The most obvious way to do this with the async/await structure you have is to just await it:
async function getData() {
const allResults = [];
let url = 'https://swapi.co/api/starships/';
do {
const res = await fetch(url);
const data = await res.json();
url = data.next;
allResults.push(...data.results);
console.log(allResults);
} while (url !== null)
let starships = allResults;
return starships;
}
async function doTheDo() {
const test = await getData();
console.dir(test);
}
doTheDo();
you can do this. starships is defined inside the loop. Additionally, you are not calling getData() function. You can store that return value like this
const result = await getData();
console.log(result);
or you can directly print like this. console.log(await getData())
async function getData() {
const allResults = [];
let url = 'https://swapi.co/api/starships/';
do {
const res = await fetch(url);
const data = await res.json();
url = data.next;
allResults.push(...data.results);
console.log(allResults);
} while (url !== null)
return allResults;
}
console.log(await getData());
Async functions return a promise, which means you have to access the return value with a .then().
However, you have another problem: starships is in the scope of the function getData() which you have defined, but not called.
So first lets call your function:
async function getData() {
const allResults = [];
// do stuff
let starships = allResults;
return starships;
}
console.log(getData());
Now you will see that your log value is [object Promise] which isn't so helpful in its current form. This is because the code outside the async function is running synchronously, which means we don't have the value yet, just a promise to maybe return the value sometime in the future.
So now we need to access the promise asynchronously using the .then() like so:
async function getData() {
const allResults = [];
// do stuff
let starships = allResults;
return starships;
}
getData().then(starships => {
console.log(starships);
});
Now you should see the info you were expecting to be logged.
You can also save promise to a variable and pass it around and access it elsewhere in your code like so:
async function getData() {
const allResults = [];
// do stuff
let starships = allResults;
return starships;
}
let starshipPromise = getData();
// time & code passes...
starshipPromise.then(starship => {
console.log(starship);
}).catch(error => {
// handle error
});
And don't forget to catch your rejected promises!
See the MDN docs on Async functions: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
And if you need more info on promises, go here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

Categories

Resources