Reputation: 1729
I have a JS program that does a whole lot of fetch() calls to a specific API. I want to abstract all the fetch() calls into a single class called "apiService" so my code will be more readable. I want the apiService to apply some intelligence and then return responses to the caller, in the following ways: - apiService should check the response to see if there are errors present, which it must always process in the same way. - fetch() will sometimes receive a "res" that is raw data and should be used as is, and sometimes it'll received json that needs a .then(res => res.json().then(res applied so it can return an object.
So I can't just do a "return fetch(..." from apiService, because apiService needs to process one or more .then() blocks with the response. But I also need to return something that causes the calling code to work asynchronously and not block and wait.
Anyone know how I could structure the apiService function to process the html responses but also return asynchronously i.e. the calling function would receive the result object after the error checking etc.
Upvotes: 2
Views: 2541
Reputation: 33199
So I can't just do a "return fetch(..." from apiService, because apiService needs to process one or more .then() blocks with the response. But I also need to return something that causes the calling code to work asynchronously and not block and wait.
This gives me the feeling that you might be misunderstanding promises a little bit. Take this example:
const doAsyncWork = () => fetch('somewhere').then(() => console.log('fetch is complete'))
// use the above function
doAsyncWork().then(() => console.log('used the fetching function'))
The output of the above code will be
fetch is complete
used the fetching function
As you can see, by chaining then
after the fetch
call, you are actually returning the result of then
, and not fetch. Another way to think of it is, what are you actually returning if you called
const result = a().b().c() // we are really returning the result of `c()` here.
With the above in mind you can most definitely do something like:
const apiCall = loc => fetch(loc).then(res => {
// do things with your response
return res
})
apiCall('someEndpoint').then(finalRes => {
console.log('this is called after fetch completed and response processed')
})
Upvotes: 2
Reputation: 524
You can use a library called axios instead of worrying about promises and data formats yourself.
However, if you still want to do it, use the following way.
you can use a method to create promises like this.
makeRequest(url, requestData) {
const response = await fetch(url, requestData)
.then(response => { console.info('network request successful to', url); return response.json() })
.then(json => {
console.info('response received for request', url, requestData, json)
return json;
})
.catch(e => {
console.error('error at request', url, requestData, e);
return e
});
return response;
}
and use the promises like this
makeRequest('someurl', {
method: 'GET'
}).then(response=>{/*Your logic*/}).catch(error=>{/*Your logic*/});
Upvotes: 0
Reputation: 1485
I thinks you can fulfill your requirement using Promise.all()
Here is an example for you.
var promise1 = Promise.resolve(3);
var promise2 = 42;
var promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
});
For more info you can refer:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Upvotes: 0
Reputation: 10927
There is a nice article about it here called "Synchronous" fetch with async/await that will break it down for you in pieces.
In Short:
You can use await
when using fetch()
:
const response = await fetch('https://api.com/values/1');
const json = await response.json();
console.log(json);
First we wait for the request to finish, Then we can wait for it to complete (or fail) and then pass the result to the json variable.
The complete example would be to use async
, because `await won't work without it:
const request = async () => {
const response = await fetch('https://api.com/values/1');
const json = await response.json();
console.log(json);
}
request();
Upvotes: 0