async/await in javascript class method with htpps call inside - javascript

I tried to make an https call and return the body containing the data, but when I tried to print it in the console it returned undefined so I used the "promises".
const https = require('https');
const baseUri = "https://apiv2.gofile.io/"
class apiGofile {
constructor(email,apikey) {
this.email=email;
this.apikey=apikey;
}
getBestServer() {
return new Promise((resolve,reject)=>{
https.get(baseUri + "getServer", (res) => {
let body="";
res.on("data", (data) => {
body += data;
});
res.on("end", () => {
body = JSON.parse(body);
resolve(body.data.server);
});
res.on("error",(e)=>{
reject(e);
});
});
});
};
}
let a = new apiGofile("a","b");
a.getBestServer()
.then(
response => console.log(response),
error => console.log(error)
);
is there any way to use await and async in my code?

You can move the following code into an asynchronous main function then call that:
async function main() {
const a = new apiGoFile("a", "b");
// await the promise instead of using .then
const response = await a.getBestServer();
console.log(response);
// you can now use response here
}
// make sure to call the function
main();
You can read more about async/await here.
You can also make class methods async:
class Foo {
async myMethod() {
const a = new apiGoFile("a", "b");
const response = await a.getBestServer();
console.log(response);
}
}

Related

Promisify a curried (higher order function) callback

I am trying to promisify (or leverage async await feature) the callback in the function getId, using new Promise(resolve => ..., but because of the usage of the higher order function getAddresses, I am a bit stumped. I am not great at functional programming. Any suggestions on how do I promisify this one?
const {queryRecord, getData} = require(“#xyzLib”);
const getId = (callback) => {
getData(“attr1”,”attr2”,getAddresses(callback));
}
const getAddresses = (callback) => (result) => {
if (!result.success) {
callback(new Error(‘Exception details’))
} else {
queryRecord(objectName, (result) => {
callback(null, result.name);
});
}
}
// invoking call
getId(async (error, zip, state) => {
if (error) {
console.log(error.message)
} else {
await fetch(encodeURI(settingsUrl), {
method: 'GET',
});
....
Since getId() accepts a callback as the last argument and that callback uses the nodejs calling convention, you can just directly use util.promisify() on getId like this:
const { promisify } = require('util');
const getIdPromise = promisify(getId);
getIdPromise().then(result => {
console.log(result);
let fetchResult = await fetch(...);
...
}).catch(err => {
console.log(err);
});
Or, if you're already inside an async function body:
try {
const result = await getIdPromise();
console.log(result);
const fetchResult = await fetch(...);
...
} catch (err) {
console.log(err);
}
You should promisify on the lowest level available, i.e. the imported functions from the library. Then you don't even need that currying. With
const { promisify } = require('util');
const xyz = require(“#xyzLib”);
const queryRecord = promisify(xyz.queryRecord);
const getData = promisify(xyz.getData);
you can write simply
async function getId() {
return getAddresses(await getData("attr1", "attr2"));
}
async function getAddresses(data) {
if (!data.success) throw new Error("Exception details");
const result = await queryRecord(objectName);
return result.name;
}
// invoking call
try {
const zip = getId();
await fetch(encodeURI(settingsUrl), {
method: 'GET',
});
} catch(error) {
console.log(error.message);
}

Axios put return undefined [React JS + Axios]

Hi all im doing an axios put to update my data. However im getting an undefined response. Thank you in advance
function that call the Axios:
export function exUpdateMovie(movie) {
Axios.put(baseURL + "/api/update", {
movieName: movie.movieName,
movieReview: movie.movieReview,
id: movie.id,
})
.then((response) => {
// console.log(response);
return response;
})
.catch((e) => {
console.log(e);
return e;
});
}
function in app.js that calls the exUpdateMovie(movie) function:
const handleUpdateMovie = (movie) => {
console.log("UpdateMovie Passed!");
try {
const res = exUpdateMovie(movie);
alert(res?.data);
} catch (error) {
console.log(error);
}
};
Output when I alert my response is:
undefined
SETTLE:
need to add async and await at the handleUpdateMovie
need to return the Axios by doing return Axios.put()
Cheers mate for helping me. Thanks alot
Yes because your api call is returning a promise where you need to wait until the promise execution completes so make your function async and wrap the API call with await.
export async function exUpdateMovie(movie) {
const result = await Axios.put(baseURL + "/api/update", {
movieName: movie.movieName,
movieReview: movie.movieReview,
id: movie.id,
})
return result
}
const handleUpdateMovie = async (movie) => {
console.log("UpdateMovie Passed!");
try {
const res = await exUpdateMovie(movie);
alert(res?.data);
} catch (error) {
console.log(error);
}
};
Because exUpdateMovie doesn't return anything. Return the Promise:
export function exUpdateMovie(movie) {
return Axios.put(/* all your Axios code */);
}
Then when consuming the result, treat it as a Promise:
exUpdateMovie(movie).then(res => {
alert(res?.data);
});

Getting 'undefined' from asynchronous response despite 'await' and 'then'

I'm trying to send a GET request, parse its response and return it to another method. Apparently I have problems handling the asynchronous response.
I want to use Node.js' standard modules, so no Axios.
// class 1: Calling API, processing and returning the response
export async function getData() {
let str = '';
const options = {
hostname: 'jsonplaceholder.typicode.com',
path: '/posts/',
method: 'GET',
json: true,
};
https
.get(options, response => {
response.on('data', chunk => {
str += chunk;
});
response.on('end', () => {
return parseJson(str);
});
})
.on('error', error => {
console.log(error);
});
}
async function parseJson(str) {
const json = JSON.parse(str);
var text;
try {
json.forEach(element => {
text += element.body;
});
// console.log(text); // I'm getting the expected output
return text;
} catch (error) {
console.log('error');
}
}
// class 2: Calling the 2 methods above
getData().then(function (value) {
console.log('DATA: ' + value); // this is called first
});
Unfortunately as output I get an undefined. Despite using async and then:
DATA: undefined
Change getData as follows
export function getData() {
return new Promise((resolve, reject) => {
let str = '';
const options = {
hostname: 'jsonplaceholder.typicode.com',
path: '/posts/',
method: 'GET',
json: true,
};
https.get(options, response => {
response.on('data', chunk => {
str += chunk;
});
response.on('end', () => {
try {
const result = parseJson(str);
resolve(result);
} catch (error) {
reject(error);
}
});
response.on('error', reject);
})
.on('error', reject);
});
}
Now it returns a Promise, which resolves to the result of parseJson(str) or rejects with the error at on('error'
And parseJson as follows - doesn't need to be async since there's nothing asynchronous about the code inside it
Also, removing the try/catch in parseJson and using try/catch in .on("end" means that you can reject the promise returned by getData if there's an error in the parseJson call
function parseJson(str) {
const json = JSON.parse(str);
let text = '';
json.forEach(element => {
text += element.body;
});
return text;
}
alternatively (IMHO better)
function parseJson(str) {
const data = JSON.parse(str); // call it data, not json
return data.map(({body}) => body).join('');
}
or even
const parseJson = (str) => JSON.parse(str).map(({body}) => body).join('');
But that's not important :p

React JS - promise returns before execution completes. Async function does not work

I am trying to load data from firebase by calling a function in which it filters data and returns them.
When I call this function in my main function, it returns "undefined". I know the data is there (console.log(postsArray)) prints the data but I guess the return executes before data is loaded.
What am I doing wrong?
calling_Function_in_Main = async () => {
const data = await FirebaseData ();
console.log(data);
};
FirebaseData is the function that I call in my main function to load data and to return them
let postsArrays=[];
const FirebaseData = async () => {
const getViewableLink = async (link) => { //some function };
const loadData = async () => {
const database = firebase.database();
const data = database.ref();
const loadProfile = data
.child('Posts')
.orderByChild('Active')
.equalTo(true)
.once('value', function gotData(data) {
Object.values(readInfo).forEach(async (element) => {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}
});
})
.catch((error) => {
console.log(error);
}
})
.then((postsArray) => {
console.log(postsArray);
return postsArray;
});
};
await loadData();
};
export default FirebaseSwipeData;
You can't use foreach with async/await because It is not asynchronous. It is blocking.
you have 2 ways to fix this:
1- Reading in sequence: you can use for...of loop
for(const element of Object.values(readInfo)) {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}
2- Reading in parallel: you can use Promise.all
await Promise.all(Object.values(readInfo).map(async (element) => {
element.Option1Link = await getViewableLink(
preLink + element.Option1Link,
);
postsArray.push(element);
}));
Hope that solves the problem, for you

What is the correct way to export an Async function module?

I have a file asyncAwait.js that has a simple function:
async function doStuff() {
return(`Function returned string.`);
}
module.exports.doStuff = doStuff;
In another module, testing.js, I invoke and all works as expected:
var functions = require(`./functions`);
(async () => {
const test = await functions.asyncAwait.doStuff();
console.log(test);
})();
This logs "Function returned string." to the console.
All good.
However, if I use axios in asyncAwait.js:
const axios = require(`axios`);
async function doStuff(parameter) {
const url = `https://jsonplaceholder.typicode.com/posts/1`;
const getData = async url => {
try {
const response = await axios.get(url);
const data = response.data;
console.log(data);
} catch (error) {
console.log(error);
}
};
return(getData(url));
}
module.exports.doStuff = doStuff;
Then in testing.js:
var functions = require(`./functions`);
(async () => {
const test = await functions.asyncAwait.doStuff();
console.log(test);
})();
This logs undefined.
Why does the function call return undefined in the second example?
In your example getData has no return. In this case your function will implicitly return undefined. To fix it you could change that function to the following:
const getData = async url => {
try {
const response = await axios.get(url);
return response.data;
} catch (error) {
return error
}
};
module.exports.doStuff = doStuff;
May I suggest you :
module.exports=doStuff;
Or
exports.doStuff
and maybe but not sure what you're trying to achieve
replace
return(getData(url));
by
return(()=>{return getData(url)});

Categories

Resources