I have an async function making an api request. Once completed, it calls a different async function making an api request 4 times (intended to go in the order it's called). But every time it runs, those api requests return data in a random order.
First, I call fetchSearch, this works as expected.
const fetchSearch = async () => {
var myHeaders = new Headers();
myHeaders.append("x-app-id", "...");
myHeaders.append("x-app-key", "...");
var requestOptions = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
await fetch(`https://trackapi.nutritionix.com/v2/search/instant?query=${search}`, requestOptions)
.then(response => response.text())
.then(
result => (
handleSearch(JSON.parse(result).common)
)
)
.catch(error => console.log('error', error));
}
This calls handleSearch. I'm probably doing something wrong here.
const handleSearch = (data) => {
const dataList=[]
for (var key in data) {
if (data.hasOwnProperty(key)) {
dataList.push(data[key])
}
}
if (dataList[0] !== undefined) {
setSearchResults([dataList[0], dataList[1], dataList[2], dataList[3]])
fetchNutrition(dataList[0].food_name)
.then(() => {fetchNutrition(dataList[1].food_name)})
.then(() => {fetchNutrition(dataList[2].food_name)})
.then(() => {fetchNutrition(dataList[3].food_name)})
} else {
setSearchError(true)
}
}
handleSearch calls fetchNutrition:
const fetchNutrition = async (foodName) => {
var h = new Headers();
h.append("accept", "application/json");
h.append("x-app-id", "...");
h.append("x-app-key", "...");
h.append("x-remote-user-id", "1");
h.append("Content-Type", "application/json");
var requestOptions = {
method: 'POST',
headers: h,
body: JSON.stringify({ "query": foodName }),
redirect: 'follow'
}
await fetch("https://trackapi.nutritionix.com/v2/natural/nutrients", requestOptions)
.then(response => response.text())
.then(result => {setNutritionResults(nutritionResults => [...nutritionResults, JSON.parse(result)])})
.catch(error => console.log('error', error))
}
With an array of 4 strings from fetchSearch, handleSearch and fetchNutrition should be going through each string and adding the corresponding nutrition JSON string to the nutritionResults array state (in the correct order in the array).
Every time it runs, all the nutrition results are returned in a random order in the nutritionResults array, and I'm assuming it's because handleSearch isn't calling the functions in the correct order. Or I'm missing another issue.
For example, if fetchSearch returns ["apple", "apples", "apple juice", "apple pie"], nutritionResults will end up as an array of length 4 but in a random order every time it runs.
handleSearchwill start thefetchNutritionand keep executing without waiting for it, since, you don't wait for it - also, mixingasync/awaitwith.then/.catchis never a good ideafetch()requests complete when they complete. You cannot rely on any particular order..then(response => response.text()).then(result => ..... JSON.parse(result) ...)... why not useresponse.json()then you won't need toJSON.parsethe result