Use data from one api call in another api call concurrently - javascript

How to use data as a result from api call as a response in another concurrently?
I've got this function
const foo = async() => {
await firstCall()
await secondCall()
}
calling firstCall() i want to get data and save them inside some variable and when this data is received use data as params inside secondCall()

Declare a variable data inside your async function foo and assign it a value which is the value returned from calling the firstCall function:
const foo = async() => {
const data = await firstCall()
await secondCall(data)
}
For more info you can read documentations at MDN - async function.

Related

Action is being dispatched before the api call so payload is being send as promise

import {fetchData} from "../common/helpers";
import {updateData} from "../Data/ducks/actions"
fetchData will check for is data available in local storage or not otherwise it will make an api call to get the data.
class Data {
dataCheck(id) {
if (isDataAvailable) {
let data;
const fetchEligibleData = async () => {
let dataAvailabilityCheck = fetchData("DATA_EMPLOYEE");
data = dataAvailabilityCheck;
if (dataAvailabilityCheck instanceof Promise) {
data = await dataAvailabilityCheck;
}
return data;
}
const eligibleData = fetchEligibleData();
Store.dispatch(updateData({ availableData: eligibleData }))
}
}
}
export default new Data
in the above code the important part starts from if(isDataAvailable).
payload for the updateData action is always being sent as promise. this is not expected behaviour.
first promise should be resolved then the data will be passed to the updateData action.
Please suggest me the approach to solve the promise before store action being triggered.
Set variable data to the result of the promise if it is successful. I.E. fetch(APIURL).then(res => data = res);
Or, fetch(APIURL).then(async res => data = await res.JSON());
I realized your api call is elsewhere, and it looks like you're querying it for specific 'Employee' info. Without seeing that, I'm not sure what you're doing there. I don't know that you should be awaiting a promise at that point, but if you are, you still will need to get the result of it.

When I get firebase data and I log it it returns the document file but when I output it it returns a promise

I have been working with firebase and am having trouble with this code.
The goal of the code is to get the document data with the document id.
const getPostData = async (postId) => {
const postData = await getDoc(doc(db, 'posts', postId));
console.log(postData.data()); // Returns the document data
return postData.data();
}
const postData = getPostData(id);
console.log(postData) // Returns a promise
I am extremely confused because I return the document data which when I log gives me the actual document data but when I set it as a variable it does not do the same.
When you use a function like async, it returns a Promise automatically. So the problem is in logic.
What happens:
You call getPostData
It is an async function, so, its return is Promise
The larger scope is not an async scope, so the console.log is executed right after, not waiting for the execution of what is inside getPostData
console.log returns a Promise
Try something like:
const [postData, setPostData]= useState()
const getPostData = async (postId) => {
const postData = await getDoc(doc(db, 'posts', postId));
if (postData.exists()) {
console.log(postData.data()); // Returns the document data
setPostData(postData.data());
} else {
console.log("No posts!");
}
}
...
getPostData(id);
...
console.log(postData)
Since you've marked getPostData as async it returns a Promise and not an immediate value.
To get the value from the promise when calling getPostData, you can either use then():
getPostData(id).then((postData) => {
console.log(postData)
})
Or you can use await:
const postData = await getPostData(id);
console.log(postData)

How to stub promise.all in sinon

I have a function which has 2 APi calls. Iam destructuring the response and sending each response to different functions to perform some operation. I need to write test case to make API call., fetch response & pass it to respective functions.
This is my code
async _fetchComponentDetails() {
const [firstResponse, secondResponse] = await Promise.all([
this._getfirstApiResponse(param1, param2),
this._getSecondApiResponse(param1, param2),
]);
this.formatFirstApiResult = await componentSerives.formatFirstResponseData(firstResponse);
this.formatSecondApiResult = await componentSerives.formatSecondResponseData(secondResponse);
}
This is my Service call
async _getfirstApiResponse(param1, param2) {
const url = 'api/firstApi';
const firstResponse = await componentSerives.fetchApiDetails(url, param1, param2);
return firstResponse;
}
async _getSecondApiResponse(param1, param2) {
const url = 'api/secondApi';
const secondResponse = await componentSerives.fetchApiDetails(url, param1, param2);
return secondResponse;
}
This is the Test case I written
it('it should make make API calls for first and second',async () => {
sinon.stub(componentSerives, 'fetchApiDetails').resolves(bannerResponse);
});
The issue iam facing is., I dont know how to send both first & second APi response in resolves();
on passing it as an array of objects like below., I see firstResponse & secondResponse loading in both objects.
[{firstResponse, secondResponse}]
can you help me how to stub both the APis and assign it to different responses in destructuring?
You are stubbing the wrong thing, according to your own test:
it('it should make make API calls for first and second',async () => {
If you are testing fetchApiDetails you cannot stub that function out. That makes no sense! Then you would just be testing your own stub.
What you need to stub out or inject, are its dependencies: _getfirstApiResponse and _getSecondApiResponse. Stub those out simply by having them just resolve some value:
const firstResponse = 42;
const secondResponse = -42;
sinon.replace(componentSerives, '_getfirstApiResponse', sinon.fake.resolves(firstResponse));
sinon.replace(componentSerives, '_getSecondApiResponse', sinon.fake.resolves(secondResponse ));
await componentSerives.fetchApiDetails();
assertEquals(componentSerives.formatFirstApiResult, "Result: 42");
assertEquals(componentSerives.formatSecondApiResult, "Result: -42");

Async/Await on Callback not waiting

I am querying AMPS SOW using javascript API. My functions look like this:
sow_query = async(topic, filter, options) => {
await this.connection
await this.client.sow(this.onMessage, topic, filter, options)
return this.message
}
onMessage = (message)=>{
this.message.push(message.data)
}
//Calling functions
const getData = async(date) =>{
let data = await getAmpsData(date)
}
async getAmpsData(date){
const filter = "some filter"
const data = await ampsClient.sow_query(topic, filter)
data.forEach((element) => console.log(element))
}
It looks like my call to ampsClient.sow_query doesnt wait for the callback to finish so returns an empty list. Therefore, I cannot loop through the data in my calling function getAmpsData.
I know it has to do with async/await because if I simply do console.log(data) in getAmpsData i can see the data (perhaps after 2 seconds) when the promise is resolved. Is there anyway i can get this working?
If I understand you correctly, data in getAmpsData is an array as expected, but data in getData is undefined. It's not an async/await problem, you just forgot to add return data; to getAmpsData.
I not sure about what package you are using. But, maybe, it using a callback function to get the result of .sow function - message.data.
With your logic, onMessage function will be called after data.forEach done, you can try adding a console.log line to onMessage function.
Maybe, the package has an important reason to do that. But, to fix this issue, you can wrap .sow function into a promise.
sow_query = async (topic, filter, options) => {
await this.connection // ???
return new Promise((resolve) => { // wrap in a promise
this.client.sow( // no need to wait .sow
(message) => {
resolve(message.data); // just resolve when we get the message's data
},
topic, filter, options)
});
}
//Calling functions
const getData = async (date) => {
let data = await getAmpsData(date)
}
async getAmpsData(date) {
const filter = "some filter"
const data = await ampsClient.sow_query(topic, filter)
data.forEach((element) => console.log(element))
}

Export the value returned from an async/await function in ES6

Is it possible to export the value of an await function from an ES6 class? For example, I have a class with a function named getDetails which looks like this
class Config {
static async getDetails() {
let response = await fetch('url/where/details/are')
let data = await response.json()
return data;
}
}
export { Config }
When I import this class into another file, and call User.getDetails(), whats returned is Promise {<pending>}. Is there a way to make the stack wait for a response from the API first?
Why not just use await in your parent file too?
// your async function
const res = await User.getDetails()
// here you have res
Alternatively, you can use .then
User.getDetails()
.then(res => {
// use res here
})
When calling User.getDetails(), you need to either use .then() or use await. Remember – you can only use await within an async function, so you would either do
async myFunction() {
const data = await User.getDetails();
}
or
myFunction() {
const data = User.getDetails().then(res => {})
}

Categories

Resources