Home > Enterprise >  API resolved without sending a response - Next.js
API resolved without sending a response - Next.js

Time:10-04

I've this code to get nearby places and nearby beaches from a point, with Google maps. This is called from a Next.js component, via the useSWR hook.

All the data is returned correctly, but before first Axios call (const fetchNearbyPlaces = async (urlWithToken = null) => {...), I'm receiving this error in the console:

API resolved without sending a response for /api/google/places/33.807501/-78.70039, this may result in stalled requests.

I can't figure out what the error is, although there may be several because I'm a novice. I appreciate any suggestion.

const axios = require("axios");
const GetNearbyPlaces = async (req, res) => {
  const {
    latitude,
    longitude,
  } = req.query;

  const radius = 50000;

  const types = [
    "airport",
    "tourist_attraction",
    "amusement_park",
    "aquarium",
    "art_gallery",
    "bar",
    "museum",
    "night_club",
    "cafe",
    "restaurant",
    "shopping_mall",
    "store",
    "spa",
  ];

  function checkFunc(arr, val) {
    return arr.some(arrVal => val === arrVal);
  }

  const url = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=${radius}&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`;

  const beachesUrl = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${latitude},${longitude}&radius=${radius}&type=natural_feature&key=${process.env.CW_GOOGLE_MAPS_API_KEY}`;

  try {
    let results = [];
    let beaches = [];
    const fetchNearbyBeaches = async (urlWithToken = null) => {
      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 {
          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) => {
      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}`;

          setTimeout(() => {
            fetchNearbyPlaces(newUrl);
          }, 2000);
        } else {
          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;
          
          return fetchNearbyBeaches();
        }
      });
    };

    fetchNearbyPlaces();
  } catch (err) {
    res.status(500).json({
      message: err.message,
      statusCode: 500,
    });
  }
};

export default GetNearbyPlaces;

CodePudding user response:

The problem is with the backend application not the frontend component.

Nextjs expects a response to have been sent when the api handler function exits. If for example you have a databaseCall.then(sendResponse) in your api handler function what happens is that the handler function exits before the database returns.

Now this is not a problem if the database does return after that and sends the response, but it is if for example the database has an error. Because the handler function exits without a response already being sent Nextjs can't be sure that at that point there isn't a stalled request.

One way to fix this is by await-ing the db call(or whatever other async function you call) thereby preventing the handler function from exiting before some kind of response has been send.

CodePudding user response:

The solution was added this object to mi API code.

export const config = {
  api: {
    externalResolver: true,
  },
};

Documentation: https://nextjs.org/docs/api-routes/request-helpers

  • Related