I want to make an async fetch call with await operator. A forEach method iterates over an array of API endpoints, then inserts some values into a local object. See below.
It works great, except - sometimes the values entered into dataModel[index].retailers[i+1] does not align with the index. For example, products for api object 2 will be inserted into local object 4.
I think this has something to do with the asynchronous nature of the request, I thought await might resolve it but it hasn't. Can anyone show me the way?
var api_obj; // Defining async function async function getapi(url, index) { // Storing response var response = await fetch(url).then(res => res.json()).then(data => api_obj = data).then(function() { //iterate over the API object and store required values //in our local dataModel object Object.keys(api_obj[0].RetailerProducts).forEach(function(i) { var i = parseInt(i, 10) dataModel[index].retailers[i + 1] = { retailer: api_obj[0].RetailerProducts[i].RetailerName, url: api_obj[0].RetailerProducts[i].ClickThruUrl, price: api_obj[0].RetailerProducts[i].Price.toFixed(2), logo: api_obj[0].RetailerProducts[i].RetailerLogoUrl, name: api_obj[0].RetailerProducts[i].RetailerProductName } }) }); } //iterate over dataModel and call each API endpoint Object.keys(dataModel).forEach(function(i) { // Calling that async function getapi(dataModel[i].apiEndpoint, i); })
Here is what dataModel looks like:
var dataModel = { '1': { 'retailers': {} }, '2': { 'retailers': {} }, '3': { 'retailers': {} } }
I figured out how to solve the ordering issue, here was the solution, basically utilising another .then
method that calls the next function and a counter sitting in global scope:
var apiCounter = 1; let csApiCall = () => { var api_obj; // Defining async function async function getapi(url, index) { // Storing response var response = await fetch(url).then(res => res.json()).then(data => api_obj = data).then(function() { //iterate over the object and store required values //in our dataModel object Object.keys(api_obj[0].RetailerProducts).forEach(function(k) { var k = parseInt(k, 10) dataModel[index].retailers[k + 1] = { retailer: api_obj[0].RetailerProducts[k].RetailerName, url: api_obj[0].RetailerProducts[k].ClickThruUrl, price: api_obj[0].RetailerProducts[k].Price.toFixed(2), logo: api_obj[0].RetailerProducts[k].RetailerLogoUrl, name: api_obj[0].RetailerProducts[k].RetailerProductName } }) }).then(function() { if (apiCounter < Object.keys(dataModel).length) { apiCounter++; getapi(dataModel[apiCounter].apiEndpoint, apiCounter); } }); } getapi(dataModel[apiCounter].apiEndpoint, apiCounter); };
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.