Finding Bounding Box using Mapbox GL on React Native
Tags: reactnative, mapbox, javascript, typescript
Published: 2022-07-16 20:57:03

Recently at work, I have been using [Maps SDK for React Native](https://docs.mapbox.com/help/glossary/maps-sdk-for-react-native/) to implement a map feature for our app.
My task was mainly to get the bounding box to determine the pins to display on the screen since there would be performance issues if I load all the pins even outside of the viewport. I have struggled and wrapped my head around this task for a few days and I hope others have a better time figuring out this issue of the bounding box not rendering at all due to promise issues. This is also a [Relevant Issue](https://github.com/nitaliano/react-native-mapbox-gl/issues/1353).

[Maps SDK for React Native](https://docs.mapbox.com/help/glossary/maps-sdk-for-react-native/) is based on [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/guides/). Here is the [documentation for Mapbox Maps SDK for React Native](https://github.com/rnmapbox/maps) which is a community-maintained React Native library that provides reusable JS components for integrating Mapbox maps into iOS and Android apps. Since it is just maintained by volunteers and is constantly updating, some examples of the props or the functions of the existing components were not clear enough.

The function I was trying to use was `getVisibleBounds()` of the [MapView](https://github.com/rnmapbox/maps/blob/main/docs/MapView.md) component. `getVisibleBounds()` returns the coordinate bounds(ne, sw) visible in the users’s viewport.
This is the example usage in the documentation:
`const visibleBounds = await this._map.getVisibleBounds();`
I have rendered my MapPage as a functional component, which did not allow me to make use of `this._map`. 

My initial attempt was to create an async function that would return the bounding box as such:
```js
   const renderBox = async () => {
      try {
        const visibleBounds = await MapboxGl.MapView.getVisibleBounds();
      } catch(e) {
        return e
      }
        return visibleBounds
    }
```
However, this function threw an error message like this: `Objects are not valid as a React child (found: object with keys {_U, _V, _W, _X})`. This turned out to be a promise issue, and the following is a way to get around it.

I first created a region state that has an initial state of a location like this: `const [region, setRegion] = useState(location)`. `location` is an array that represents a coordinate as such `[longitude, latitude]`.

By making use of the useEffect hook, I logged all the properties of the `region` in the user's viewport as such.
`useEffect(() => console.log(region), [region])`
The following was the log.
```
[Sat Jul 16 2022 15:40:42.298]  LOG      {"geometry": {"coordinates": [-87.58876641738603, 42.53691705896288], "type": "Point"}, "properties": {"animated": false, "heading": -0, "isUserInteraction": true, "pitch": 0, "visibleBounds": [[Array], [Array]], "zoomLevel": 4}, "type": "feature" }
```

So I inspected the `properties` property of this object by logging `region.properties` and got the following log.
```
[Sat Jul 16 2022 15:40:58.570]  LOG      {"animated": false, "heading": -0, "isUserInteraction": true, "pitch": 0, "visibleBounds": [[-78.56114431259272, 51.56343338258], [-96.64150070383894, 32.005443763933826]], "zoomLevel": 4}
```
Thus, by getting `region.properties.visibleBounds`, I was able to get the two coordinates of the user's viewport `[[ne],[sw]]` in every region change.

I hope this article helps others who have been running into similar issues. If there is a better fix by using the `getVisibleBounds()` function directly, it would also be greatly appreciated!