Getting 'Cannot read properties of null (reading 'sw')' error when integrating RapidAPI with Google Maps

I’m stuck with a null reference error when trying to pass map boundaries to my API call

I have two versions of my code. One works fine with hardcoded values, but when I try to use dynamic coordinates from Google Maps, I get this error.

Working version with static coordinates:

import fetch from 'node-fetch';

const API_ENDPOINT = "https://travel-advisor.p.rapidapi.com/restaurants/list-in-boundary";

const requestConfig = {
  params: {
    bl_latitude: "11.847676",
    tr_latitude: "12.838442", 
    bl_longitude: "109.095887",
    tr_longitude: "109.149359",
  },
  headers: {
    "x-rapidapi-host": "travel-advisor.p.rapidapi.com",
    "x-rapidapi-key": "my-key",
  },
};

export const fetchRestaurantData = async () => {
  try {
    const response = await fetch(API_ENDPOINT, requestConfig);
    const result = await response.json();
    return result.data;
  } catch (err) {
    console.error(err);
  }
};

App component (working):

const [mapBounds, setMapBounds] = useState(null);
const [restaurants, setRestaurants] = useState([]);

useEffect(() => {
  fetchRestaurantData().then((result) => {
    setRestaurants(result);
  });
}, []);

Broken version with dynamic parameters:

export const fetchRestaurantData = async (southwest, northeast) => {
  try {
    const response = await fetch(API_ENDPOINT, {
      params: {
        bl_latitude: southwest.lat,
        bl_longitude: southwest.lng,
        tr_longitude: northeast.lng, 
        tr_latitude: northeast.lat,
      },
      headers: {
        "x-rapidapi-host": "travel-advisor.p.rapidapi.com",
        "x-rapidapi-key": "my-key",
      },
    });
    const result = await response.json();
    return result.data;
  } catch (err) {
    console.error(err);
  }
};

App component (broken):

useEffect(() => {
  navigator.geolocation.getCurrentPosition(
    ({ coords: { latitude, longitude } }) => {
      setCurrentLocation({ lat: latitude, lng: longitude });
    }
  );
}, []);

useEffect(() => {
  fetchRestaurantData(mapBounds.southwest, mapBounds.northeast).then((result) => {
    setRestaurants(result);
  });
}, [currentLocation, mapBounds]);

The error happens right after I made this change. I compared both versions but can’t figure out what’s wrong. Any ideas what might be causing this?

Your useEffect dependency array and timing are the problem. When the component mounts, mapBounds starts as null, but your effect runs right away and tries to access mapBounds.southwest before Google Maps actually sets the bounds. I encountered this issue a few months ago on a similar feature. Just add a null check before calling your API function: if (mapBounds && mapBounds.southwest && mapBounds.northeast) { fetchRestaurantData(mapBounds.southwest, mapBounds.northeast).then... }. Also, double-check that your Google Maps onBoundsChanged callback is actually setting the mapBounds state. The working version doesn’t have this issue because it doesn’t rely on dynamic bounds that might not exist yet.

Your fetch config is wrong for the dynamic version. You’re passing params to fetch options, but fetch doesn’t handle query parameters like that. In your working version, you defined requestConfig with params but aren’t actually using them in the URL. For the dynamic version, build the query string manually and add it to your endpoint URL. Try this: const queryParams = new URLSearchParams({ bl_latitude: southwest.lat, bl_longitude: southwest.lng, tr_longitude: northeast.lng, tr_latitude: northeast.lat }); const response = await fetch(${API_ENDPOINT}?${queryParams}, { headers: {...} });. You’re getting the null error because fetch is failing silently from the malformed request, so your response processing tries to read properties of null.

Classic race condition. Your second useEffect runs before mapBounds gets populated from Google Maps. Add if (!mapBounds?.sw) return; at the top of that effect. Also noticed your working version uses hardcoded strings but the broken one uses numbers - convert to strings in case the API’s picky about data types.