I've been having a problem with the Reverse Geocode API provided by TomTom where I get 429
responses back, because I am mapping over 72
latitude and longitude objects to the API.
So I decided tried to make a function which would wait 5
seconds before firing another request; As TomTom advises 5
seconds between requests.
I thought it was totally kosher to (like in my function below) call a function, (like in my case) call Topography.getTopography(latLng)
and then off of that then
call, I can take that result and feed it to the TomTom request. Is this wrong? Or is it my setTimeout?
Here is my function
async function getTopographyData(latLang) {
const retryTimes = 5;
let counter = 0;
var newObj = {};
Topography.getTopography(latLang, options)
.then((results) => {
newObj.topography = results;
newObj.latlng = latLang;
return newObj;
})
.then(async (newObj) => {
var { lat, lng } = newObj.latlng;
let result = await axios.get(
`https://api.tomtom.com/search/2/reverseGeocode/crossStreet/${lat},${lng}.json?limit=1&spatialKeys=false&radius=10000&allowFreeformNewLine=false&view=Unified&key=${process.env.TOM_TOM_API}`
);
var { addresses } = result?.data;
var { address, position } = addresses[0];
var [lat, lng] = position.split(",").map((p) => +p);
newObj = {
...newObj,
latlng: { lat, lng },
address,
};
dispatch({ type: "setTopographyData", payload: newObj });
})
.catch(function (error) {
if (
(error.response?.status == 403 || error.response?.status == 429) &&
counter < retryTimes
) {
counter++;
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve(getTopographyData(counter));
}, 5000);
});
} else {
console.log("error", error);
}
});
}
Any help would be appreciated.
Update while num8er's solution works, I believe there must be a problem with TomTom as it stops at 45 (getting a reverseGeoCode look up for 45 markers latlang objects) and spits back errors in the console. Furthermore when I click the link in the console I can see the response in the browser?!
How about refactoring it with regular loop with pause and break to make code more readable:
async function getTopographyData(latLng) {
const retryTimes = 5;
const topographyData = {
latlng: latLng,
address: null,
};
const pause = (ms) => new Promise(resolve => setTimeout(resolve, ms));
for (let counter = 1, canRetry = false; counter <= retryTimes; counter++) {
try {
const topography = await Topography.getTopography(latLng, options);
topographyData.topography = topography;
const { lat, lng } = topographyData.latlng;
const response = await axios.get(
`https://api.tomtom.com/search/2/reverseGeocode/crossStreet/${lat},${lng}.json?limit=1&spatialKeys=false&radius=10000&allowFreeformNewLine=false&view=Unified&key=${process.env.TOM_TOM_API}`
);
if (response?.data) {
const { addresses } = response.data;
const { address, position } = addresses[0];
const [lat, lng] = position.split(",").map((p) => +p);
topographyData.address = address;
topographyData.latlng = {lat, lng};
}
dispatch({ type: "setTopographyData", payload: topographyData });
}
catch (error) {
console.error(error);
canRetry = [403, 429].includes(error.response?.status);
}
if (!canRetry) {
break;
}
await pause(5000);
}
}