How to get final result data from a function - javascript

I've been trying to make function(see bellow) to work. If i call this function in my test like this:
test.meta({ CID: 'C67', type: TestType.Critical }).timeouts({
pageLoadTimeout: 5000,})(
'Test to GetData',
async (t:TestController) => {
// When
const result = getData.getFinalData()
const finalResult = JSON.stringify(result)
console.log(finalResult)
})
In the log i get empty result:
Case Discovery
{}
But if i do console.log(data) inside the function, i do get the proper data.
So i just want to know how to get that data. As I will need later to use it for my test.
I was intending to use it like this:
const randomCaseId = finalResult[getRandomInt(1000)].caseId.toString()
public async getFinalData () {
fetch(TOKEN_API, {
method: 'post',
body: new URLSearchParams(details),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
})
.then((res: { json: () => any; }) => res.json())
.then((json: any) => {
const token = (json.accessToken.toString())
console.log(token),
fetch(DATA_API, {
method: 'GET',
headers: { 'Content-Type': 'application/json' ,'authorization': `Bearer ${token}`}})
.then((res: { json: () => any; }) => res.json())
.then((json:any)=>{
const data = JSON.stringify(json)
return data;
}
)
})}

since getFinalData doesn't return anything, and it is async you'll never get anything but a promise that resolves to undefined when calling that function.
Why is getFinalData tagged async since you never use await. I would use async/await for simple code, rather than the .then chain you are using
To access the result of calling that function, you'll either need to await it, or use .then on the result - since the calling funciton is async, use await
Rewrite your code like
test.meta({ CID: 'C67', type: TestType.Critical })
.timeouts({pageLoadTimeout: 5000,})('Test to GetData', async (t:TestController) => {
// When
const finalResult = await getData.getFinalData();
console.log(finalResult)
})
and
public async getFinalData () {
const tokenres = await fetch(TOKEN_API, {
method: 'post',
body: new URLSearchParams(details),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
});
const tokendata = await tokenres.json();
const token = tokendata.accessToken.toString();
console.log(token);
const res = await fetch(DATA_API, {
method: 'GET',
headers: { 'Content-Type': 'application/json' ,'authorization': `Bearer ${token}`}
});
// ** see note below, don't do the next two lines like this
const data = await res.json();
return data;
}
This code uses async/await properly, and doesn't stringify the data into JSON, twice!
Also, note
const data = await res.json();
return data;
can be the single line
return res.json();
Because that's how promises work

There are several problems here:
When you return a value inside the function which you've passed to then, it would not be returned as the value of the outer function
getFinalData is a async so it would return a promise
getFinalData is returning a promise but you never pass a value as the resolved data
You can use following code, which wait for the response:
test.meta({
CID: 'C67',
type: TestType.Critical
}).timeouts({
pageLoadTimeout: 5000,
})(
'Test to GetData',
async (t: TestController) => {
// When
const result = await getData.getFinalData()
const finalResult = JSON.stringify(result)
console.log(finalResult)
})
And also make sure to wait for the fetch and return the resolved value:
public async getFinalData() {
const res = await fetch(TOKEN_API, {
method: 'post',
body: new URLSearchParams(details),
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
})
const json = await res.json();
const token = (json.accessToken.toString())
console.log(token);
const response = await fetch(DATA_API, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'authorization': `Bearer ${token}`
}
});
return response.json();
}

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();
},[])

How to return data from Promises if second fetch request depends on first?

I want to get some data from 2 apis, but i need some properties from the first api to make the fetch request to the second api. I also need the entire response from the first api.
export const fetchTrip = createAsyncThunk(
'trip/fetchTrip',
async (payload, thunkAPI) => {
const result = fetch(
'http://localhost:5000/user/trip/' + payload, {
mode: 'cors',
credentials: 'include',
method: "get",
headers: {
'Content-Type': 'application/json'
},
})
.then(response => response.json())
.then(data => {
const places= data.trips[0].places
return Promise.all(places.map(place=>
fetch('http://localhost:5000/api/tripadvisor/' + place.id)
))
.then(resp => resp.json())
})
console.log(result)
return result
}
)
So the first fetch request will respond with some data such as
{
title: "Cali Trip",
budget: "1000",
places: [
{id: "123"},
{id: "234"},
{id: "345"}
]
}
I am using the place's id to fetch more details about that place. in the end, i want to return the trip detail from the first api, and all the details of the multiple places from the second api. I've tried the above code, but my response is undefined. ty in advance for any help!!
This would be a lot cleaner if you didn't mix async / await with .then().
What you can do is return the response from the first request with the places array re-assigned with the values resolved from the secondary requests.
export const fetchTrip = createAsyncThunk(
"trip/fetchTrip",
async (payload, thunkAPI) => {
const res = await fetch(
`http://localhost:5000/user/trip/${encodeURIComponent(payload)}`,
{
credentials: "include", // cookies? Do you even need this?
}
);
if (!res.ok) { // don't forget to check for failures
throw res;
}
// pull out the first "trip" from the "trips" array
const {
trips: [{ places, ...trip }],
} = await res.json();
// respond with the "trip"
return {
...trip,
// resolve "places" by mapping the array to a new promise
// and awaiting its result
places: await Promise.all(
places.map(async ({ id }) => {
const placeRes = await fetch(
`http://localhost:5000/api/tripadvisor/${encodeURIComponent(id)}`
);
// again, check for errors
if (!placeRes.ok) {
throw placeRes;
}
// resolve with the place data
return placeRes.json();
})
),
};
}
);
Since you are already making the function async, you could use await to make it more easy to follow, something along these lines, just a sketch for you to elaborate:
export const fetchTrip = createAsyncThunk(
'trip/fetchTrip',
async (payload, thunkAPI) => {
const data = await fetch('http://localhost:5000/user/trip/' + payload, {
mode: 'cors',
credentials: 'include',
method: 'get',
headers: {
'Content-Type': 'application/json',
},
}).then((resp) => resp.json());
// here your first result
console.log(data);
const places = data.trips[0].places;
const result = await Promise.all(
places.map((place) =>
fetch('http://localhost:5000/api/tripadvisor/' + place.id).then(
(resp) => resp.json()
)
)
);
// here the second result
console.log(result);
// overwrite places with second result
return {
...data,
places: result,
};
}
);
It seems you are mixing async/await code with Promise chaining code. While that's certainly valid, if we clean up your code a bit you can see that this is trivially done if you convert all of your code to async/await:
const response1 = await fetch('...');
const data1 = await response.json();
const data2 = await Promise.all([...]);
Of course, this can be done with Promise chaining by saving the data from inner calls into a variable outside the calls, but that's a far inferior option:
let data1;
let data2;
fetch('...')
.then((response) => response.json())
.then((data) => {
data1 = data;
return Promise.all([...]);
})

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)
}
}

Data of promise result cannot be used

I've got some noob question I guess, but I can't undestand why this code not working as expected.
Problem is that I want to use result of my promise (array) to call ids that I need, but for some reason its not working as I expect. If I call b.then((customerIds) => customerIds) just after b, I got my array with values, but if I call it on body, its not working.
const a = fetch('/orders').then(rawOrders => rawOrders.json())
let b = a.then((orders) => {
let customersList = []
orders.forEach(element => {
customersList.push(element.customer)
});
return customersList
})
fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
ids: b.then((customerIds) => customerIds)
}) // Here is the problem
}).then(rawUsers => rawUsers.json()).then(users => console.log('users', users));
you can do the second fetch inside b.then callback
like:
const a = fetch('/orders').then(rawOrders => rawOrders.json())
let b = a.then((orders) => {
let customersList = []
orders.forEach(element => {
customersList.push(element.customer)
});
return customersList
});
b.then(customerIds =>fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
ids: customerIds
})
})).then(rawUsers => rawUsers.json()).then(users => console.log('users', users));
Although, I'd usually write that whole code block like
fetch('/orders')
.then(rawOrders => rawOrders.json())
.then(orders => orders.map(({customer}) => customer))
.then(ids => fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ids})
}))
.then(rawUsers => rawUsers.json())
.then(users => console.log('users', users))
.catch(err => console.error(err));
One long promise chain - with a catch at the end
Or async/await
(async () => {
try {
const rawOrders = await fetch('/orders');
const orders => await rawOrders.json();
const ids = orders.map(({customer}) => customer);
const rawUsers = await fetch('/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ids})
});
const users = await rawUsers.json();
console.log('users', users);
} catch(err) {
console.error(err);
}
})();
(the async IIFE is only needed if this code isn't inside an async function)

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;
}

Categories