How to await a function in javascript that has a promise inside? - javascript

When I have the following function:
axios
.get(
`${config.server}/getUsers.php`,
{ headers: { Authorization: `Bearer ${token}` } }
)
.catch((error) => console.error(error));
I can do something after I receive the users with .then().
But what, if I put this request in a function:
const getUsers = () => {
axios
.get(
`${config.server}/getUsers.php`,
{ headers: { Authorization: `Bearer ${token}` } }
).then(() => {
return true;
})
.catch((error) => {
console.error(error)
return false;
});
};
How can I do something if getUsers() is done and true?

You can't await a function. You can only await a promise (or other thenable).
If getUsers() returned a promise, then you could call it and await its return value:
await getUsers();
However, it doesn't. So before you can do that you have to change it so it does return a promise.
return axios.get...

You can refactor your code like this:
const async getUsers = () => {
try {
let users = await axios({
method: 'get',
url: `${config.server}/getUsers.php`,
headers: { Authorization: `Bearer ${token}` }
});
return {success: true, result: users};
} catch (error) {
return {success: false, error};
}
};
If the request was successful you can return success: true with result data. If the request failed for some reason you can return success: false and the error.
NOTE: When you use async syntax, the function will return a Promise, so you can do .then() when you call getUsers() is some other function, or you can also use async syntax.
With .then() it will look something like:
someOtherFunction() => {
getUsers().then((users)=>{
res.status(200).json();
}).catch((error))=>{
res.status(400).json(error);
}
}
With async it will look something like:
async someOtherFunction() => {
try {
let users = await getUsers();
res.status(200).json(users);
} catch (error) {
res.status(400).json(error);
}
}

Solution
The Axio-Request is a promise, and therefore, it needs to be wrapped and returned to be thenable:
Like this:
const getUsers = () => {
return axios
.get(`${config.server}/getUsers.php`, {
headers: { Authorization: `Bearer ${token}` },
})
.then(() => {
return true;
})
.catch(error => {
console.error(error);
return false;
});
};
which would let you do something like this:
getusers().then((returnedReqData)=>{
console.log(returnedReqData);
})
This is a good resource for learning how to work with promises, and how to make them thenable.

Related

React Native get return value of async function

I am trying to get pub locations data from MYSQL server and my fetch function works well. But after that, this try-catch block does not return anything. I also tried without try-catch block but it does not change anything
getPubsFromDatabase = async () => {
let response = await fetch(fetchDataUrl, {
method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
try{
let json = await response.json();
console.log(json)
return json;
}
catch (error) {
console.log(error);
}
}
And here, I am trying to get the return value of the function. But in this version, I cannot even see any console.log output. What I mean by the version is, if I put 2nd line out of the async block without "await" keyword, I can see the console.log but I it gives "undefined" then.
(async () => {
const locationsData = await getPubsFromDatabase();
console.log(locationsData)
})()
You can use then and catch in the function fetch.
const getPubsFromDatabase = () => {
return fetch(fetchDataUrl, {
method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
}).then(async (response) => {
const json = await response.json().then((data)=>{
return data;
}).catch((err)=>{
console.log('error from json method: ',err);
return { error: {
message: 'error from json method',
object: err
}};
});
console.log(json);
return json;
}).catch((error) => {
console.log('error from request: ', error);
return {
error: {
message: 'error from request', object: error
}
};
});
}
And when you use the method getPubsFromDatabase would be of the next way:
(async () => {
const locationsData = await getPubsFromDatabase();
console.log(locationsData);
})()
You can use Promise to return either result or error, In the example given below i have used axios library but you can also try same with fetch api
For Example
export const getData = () => {
return new Promise((resolve, reject) => {
const url = ApiConstant.BASE_URL + ApiConstant.ENDPOINT;
const API_HEADER = {
"Authorization": token,
};
axios
.get(url, {
headers: API_HEADER,
})
.then((res) => {
resolve(res.data);
})
.catch((error) => {
// handle error
reject(error);
console.log(error);
});
})
}
You can call the above function in component or screen like this:
getData().then(
(data) => {
}
).catch(
error => {
console.log(error)
}
)
I solved the problem by instead of returning the value from the function, I set the value inside the function. This seems to work now.
const [locationsData, setLocationsData] = useState();
getPubsFromDatabase = async () => {
let response = await fetch(fetchDataUrl, {
method: 'POST',
headers:
{
'Accept': 'application/json',
'Content-Type': 'application/json',
},
});
try{
let json = await response.json();
setLocationsData(json); // Here, I changed the value of the locationsData instead of returning
}
catch (error) {
console.log(error);
}
}
And to call the function:
useEffect(()=> {
getPubsFromDatabase();
},[])

React.js - const in async becomes undefined

const test = order.restaurantId;
console.log(test); //here test == 3
const getAvailableHours = async () =>{
console.log(test); //test == undefined
await fetch(`API Address`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
})
.then(response => {
return response.json();
})
.then(responseText => {
console.log(responseText);
})
.catch(error => {
console.log(error);
});
}
Hi, I am trying to fetch data from API by using restaurant ID but when I'm passing the ID to async it becomes undefined.
I am new in React.js, anyone has any ideas?
async await syntax allows you to avoid .then method, so you can handle promises with a more readable syntax. With try catch blocks you can handle errors, try this:
const getAvailableHours = async () => {
try {
let response = await fetch('https://api-address-goes-here/', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
let responseText = await response.json();
return responseText;
} catch (err) {
console.log(err)
}
}

How to return data from a fetch and use the data to another function

I want to use the data I get from a fetch request so I return it as an array. The return value(array) will be use to another function but I get a promise :
Promise {<pending>}
__proto__: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Array(10)
Below is the complete code
function getEmailList() {
fetch(myData.root_url + '/wp-json/wp/v2/email', {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
return response.json();
}).then(emails => {
emails.map((email) => {
emailArr.push(email.title.rendered)
})
return emailArr;
}).catch(err => console.log('failed', err))
}
function getData() {
let emailList = getEmailList();
console.log(emailList)
}
Your calling code can be
function getData() {
getEmailList().then(emailList => console.log(emailList));
}
Use async await
function async getData() {
let emailList = await getEmailList();
console.log(emailList)
}
You need to return fetch in getEmailList() and use async/await in getData().
function getEmailList() {
return fetch(myData.root_url + '/wp-json/wp/v2/email', {
method: "GET",
headers: {
'Content-Type': 'application/json'
}
}).then(response => {
return response.json();
}).then(emails => {
emails.map((email) => {
emailArr.push(email.title.rendered)
})
return emailArr;
}).catch(err => console.log('failed', err))
}
async function getData() {
let emailList = await getEmailList();
console.log(emailList)
}

How to use response from fetch() api

How to use response from fetch api?
i try to return my response, but when i try to print this values in my function, i get undefined,
can someone tell me how to use this response in different function?
my response is an json of nested objects
async fetchData() {
const url = `...`;
fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
//
})
}).then((response) => response.json())
.then(response => {;
console.log(response) //correct response
return response;
})
}
async getDataFromFetchApi() {
const data= await this.fetchData();
console.log(data); // undefined
if(data != undefined){
throw new BadRequestException();
}
return data;
}
thanks for any help
Bottom line, an async function must return a promise to work correctly. fetchData has no return value. The return response is inside of a .then, and doesn't apply to the fetchData function itself.
For the above code, the fewest modifications is simply to return fetch(...) in your fetchData function, like this:
async fetchData() {
const url = `...`;
return fetch(/* ... */)
.then((response) => response.json())
.then(response => {
console.log(response) //correct response
return response;
})
}
Alternatively you could use the async/await syntax for all it's worth, and get rid of your .thens, like this:
async fetchData() {
const url = `...`;
const resp = await fetch(/* ... */);
const json = await resp.json();
console.log(json);
return json;
}
You have to return data in the scope of fetchData function:
async fetchData() {
const url = `...`;
const response = await fetch(url, {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
//...
})
});
return response;
}

How to wrap a try catch block inside an arrow function to call an api?

I have an arrow function which returns some data from an api call. i want to wrap it up inside a try catch block like
const fetchEmployees = () => (
try{
fetch('http://localhost:6873/api/values', {
method: 'GET',
headers: {
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(names => { return names })
} catch (error) {
return error;
}
)
How could i do that? The perfectly working arrow function I have is
const fetchEmployees = () => (
fetch('http://localhost:6873/api/values', {
method: 'GET',
headers: {
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(names => names )
)
You can't use try catch on fetch because fetch is async while try catch is sync. Therefore your try catch will always pass. if we assume that you received response, and .json() fails, in second then first parameter is success function second one is fail function that executes when .json() fails
const fetchEmployees = () => (
fetch('http://localhost:6873/api/values', {
method: 'GET',
headers: {
'content-type': 'application/json'
}
})
.then(response => response.json())
.then(names => names, error => "json failed" )
)
fetchEmployees().then(success => {}, error => {})
Like this when you call fetchEmployees in first function will be executed if everything succeed, otherwise second will execute with error response, in this case hard coded string "json failed"
Turn your function into an async one:
const fetchEmployees = async () => {
try {
const response = await fetch("http://localhost:6873/api/values", {
method: "GET",
headers: {
"content-type": "application/json"
}
});
const names = await response.json();
return names;
} catch (error) {
return error;
}
};
Try to use async/await
const fetchEmployees = async () => {
try {
let response = await fetch('http://localhost:6873/api/values', {
method: 'GET',
headers: {
'content-type': 'application/json'
}
});
let json = await response.json();
return json;
} catch (error) {
return error
}
}

Categories