EDIT: The question was initially to avoid an error in the console, it was already avoided by configuring Next.JS thanks to Pablo's comment. Now I am looking for another answer, that is how to make my code work, without using setTimeout, that is why I change the title of it.
I am getting places near a point with the Google maps API.
At one point I am getting an error (indicated below) but the code continues its execution and finally returns the expected result. (That's right, everything works fine for me, only that error appears in the node console, and I would like to know what I am doing wrong so that it appears, to avoid it.)
API resolved without sending a response for /api/google/places/33.807501/-78.70039, this may result in stalled requests.
The code starts with the last line of try
when I do fetchNearbyPlaces();
, then that function is executed, which is recursive.
fetchNearbyPlaces
initially it does not receive any parameters, so I make the normal call. If the result of this call returns a next_page_token
, it indicates that I can return more results.
So, in this case, I call again fetchNearbyPlaces
but this time passing a parameter...
(AT THIS MOMENT IS WHEN I GET THE ERROR)
... until at one point the result no longer returns a next_page_token
, at that moment it enters else
, I clean the results, I call to fetchNearbyBeaches
find nearby beaches, and finally from this function I return the entire result.
I added SEVERAL console.log
to see if I can identify when the error appears, (I leave the console in the code) and what I see on the console is the following:
- llamamos a fetchnearbyplaces
- fetchNearbyPlaces indica que hay mas resultados, vuelvo a llamar
- ERROR: API resolved without sending a response for /api/google/places/33.807501/-78.70039, this may result in stalled requests.
- llamamos a fetchnearbyplaces
- fetchNearbyPlaces indica que hay mas resultados, vuelvo a llamar
- llamamos a fetchnearbyplaces
- Ya no hay mas resultados, limpio el resultado y llamo a fetchNearbyBeaches
- Desde fetchNearbyBeaches. Misma logica que para fecthNearbyPlaces
- Desde fetchNearbyBeaches. Misma logica que para fecthNearbyPlaces
- Finalmente devuelvo el resultado de la llamada
This is my code:
const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`;
const beachesUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude}%2C${longitude}&radius=${radius}&type=natural_feature&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`;
try {
let results = [];
let beaches = [];
const fetchNearbyBeaches = async (urlWithToken = null) => {
console.log("Desde fetchNearbyBeaches. Misma logica que para fecthNearbyPlaces");
await axios.get(urlWithToken ? urlWithToken : beachesUrl).then(data => {
beaches = [...beaches, ...data.data.results];
if (data?.data?.next_page_token) {
const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`;
setTimeout(() => {
fetchNearbyBeaches(newUrl);
}, 2000);
} else {
console.log("Finalmente devuelvo el resultado de la llamada");
beaches.length > 5 && beaches.splice(5);
results.length > 5 && results.splice(5);
const finalResults = [...beaches, ...results];
finalResults.length > 10 && finalResults.splice(10);
return res.status(200).json({
data: {
results: finalResults,
},
success: true,
});
}
});
};
const fetchNearbyPlaces = async (urlWithToken = null) => {
console.log("llamamos a fetchnearbyplaces");
await axios.get(urlWithToken ? urlWithToken : url).then(data => {
results = [...results, ...data.data.results];
if (data?.data?.next_page_token) {
const newUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?key=${process.env.CW_GOOGLE_MAPS_API_KEY}&pagetoken=${data.data.next_page_token}`;
console.log("fetchNearbyPlaces indica que hay mas resultados, vuelvo a llamar");
setTimeout(() => {
fetchNearbyPlaces(newUrl);
}, 2000);
} else {
console.log("Ya no hay mas resultados, limpio el resultado y llamo a fetchNearbyBeaches");
const dirtyResultsWithDuplicates = [];
results.map(result => {
return types.map(type => {
if (checkFunc(result.types, type) && !result.types.includes("lodging")) {
dirtyResultsWithDuplicates.push(result);
}
});
});
const set = new Set(dirtyResultsWithDuplicates);
const filtered = Array.from(set);
results = filtered.length > 10 ? filtered.splice(10) : filtered;
fetchNearbyBeaches();
}
});
};
fetchNearbyPlaces();
} catch (err) {
res.status(500).json({
message: err.message,
statusCode: 500,
});
}
EDIT:
This function to fetch the google api is executed from a component, throughuseSWR
const nearbyPlacesURL = resortDetails?.geoCoordinates?.lat && resortDetails?.geoCoordinates?.lon ? `/api/google/places/${resortDetails?.geoCoordinates?.lat}/${resortDetails?.geoCoordinates?.lon}/` : null;
if (nearbyPlacesURL) {
dataFetcher = url => fetch(url).then(res => res.json()).then(data => data?.data?.results);
}
const {
data: nearbyPlaces,
} = useSWR(nearbyPlacesURL, dataFetcher, {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false,
});
If I understand your code correctly, the problem is the following:
res
has not been used to give a response (the conclusion has been delegated with a timeout), the warning appears: processing has finished in the thread associated with the request but no response has yet been sent. response (surely axios does an object state checkres
).It's not clear to me why you're using a timeout and waiting two seconds instead of just calling the function, but that's the reason for the warning. You can ignore it (or disable it with the flag
externalResolver = true
, as the documentation says .Update:
I have been looking at the Google Maps documentation and have found the following:
This explains why you need to delay the request, but there is a final note explaining how they expect you to use the interface (bolds are mine):
What is really expected is that you do not have it automated: the way to avoid using
setTimeout
it is not to be so anxious when it comes to obtaining the information and only show 20 entries. If the user wants to see more, then the next 20 entries are requested.