I'm looking for a way to fetch multiple URLs at the same time. As far as I know the API can only retrieve the data I want with a single product lookup so I need to fetch multiple products at once with the url structure "/products/productID/". Note, this is in VUEJS. This is what my code looks like so far:
In my productServices.js:
const productsService = {
getCategory(productID){
const url = `${config.apiRoot}/products/${productID}`
return fetch(url, {
method: 'GET',
headers: {
'content-type': 'application/json',
'Authorization': `Bearer ${authService.getToken()}`
},
})
}
}
In my view:
data() {
return {
featuredProduct: [13,14,15],
productName: [],
productImg: []
}
}
async mounted(){
const response = await productsService.getCategory(this.featuredProduct)
const resJSON = JSON.parse(response._bodyInit)
this.loading = false
this.productName = resJSON.name
this.productImg = resJSON.custom_attributes[0].value
}
So I need to hit all three featuredProduct IDs and store the data. I'm not really sure how to loop through multiple URLS. All of my other API calls have had all the data readily available using search params but for the specific data I need here ( product image ), it can only be seen by calling a single product.
Any help is much appreciated!
Like Ricardo suggested I'd use Promise.all
. It takes in an array of promises and resolves the promise it returns, once all the passed ones have finished (it resolves the promises in the form of an array where the results have the same order as the requests).
Docs
Promise.all([
fetch('https://jsonplaceholder.typicode.com/todos/1').then(resp => resp.json()),
fetch('https://jsonplaceholder.typicode.com/todos/2').then(resp => resp.json()),
fetch('https://jsonplaceholder.typicode.com/todos/3').then(resp => resp.json()),
]).then(console.log)
Using map
+ Promise.all
(tested)
Promise.all([1, 2, 3].map(id =>
fetch(`https://jsonplaceholder.typicode.com/todos/${id}`).then(resp => resp.json())
)).then(console.log);
if you have multiple products in an array which need to be fetched, you could just use:
Code not tested
Promise.all(productIds.map(productId =>
fetch(`https://url/products/${productId}`)
)).then(() => {/* DO STUFF */});
Little suggestion on storing your data:
If you store everything in one array, it makes to whole job way easier. So you could do
fetchFunction().then(results => this.products = results);
/*
this.products would then have a structure something like this:
Array of Obejcts: {
name: "I'm a name",
displayName: "Please display me",
price: 10.4
// And so on
}
*/
Because you have an array of products, I'd start by changing your state names:
data() {
return {
productIds: [13, 14, 15],
productNames: [],
productImages: [],
};
},
Then you can use Promise.all to fetch the products in parallel:
async mounted() {
const responses = await Promise.all(
this.productIds.map(id => productsService.getCategory(id))
);
responses.forEach((response, index) => {
const resJSON = JSON.parse(response._bodyInit);
this.productNames[index] = resJSON.name;
this.productImages[index] = resJSON.custom_attributes[0].value;
});
this.loading = false;
}
You could also consider refactoring getCategory
do the parsing for you and return an object containing a name
and an image
- that way, mounted
wouldn't have to know about the internal response structure.
Check the Promise.all
method
Maybe you can create the calls that you need by iterating into your data
and then request them in bulk.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With