Peter G.
Peter G.

Reputation: 8034

Geocode multiple addresses with React

I am using the react-native-geocoder package to geocode multiple adresses. The problem is that apparently my code has some issue with batch requests.

Why the code works for individual requests and not for batch requests and is there a way to get around this error?

async getLocations(locations) {
  Geocoder.fallbackToGoogle(GEOCODE_API_KEY);
  this.setState({
    annotations: await Promise.all(locations.map(this.getLocation))
  });
}

async getLocation(location) {
  try {
    let res = await Geocoder.geocodeAddress(location.address);
    console.log("RESULT:", location.address, await res[0].position);
    return (
      {
        latitude: await res[0].position.lat,
        longitude: await res[0].position.lng,
        title: location.provider,
        subtitle: location.address,
      }
    );
  }
  catch(err) {
    console.log("Error fetching geodata:", err);
  }
  return null;
}

result (only last request working):

Error fetching geodata Error: geocodePosition failed(…)
Error fetching geodata Error: geocodePosition failed(…)
Error fetching geodata Error: geocodePosition failed(…)
Error fetching geodata Error: geocodePosition failed(…)
Error fetching geodata Error: geocodePosition failed(…)
RESULT getLocationPosition Object {lat: 22.544028, lng: 19.124154}
Possible Unhandled Promise Rejection (id: 0):
Cannot read property 'id' of null
TypeError: Cannot read property 'id' of null
    at http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:35937:11
    at Array.map (native)
    at Constructor.render (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:35928:38)
    at Constructor.proxiedMethod [as render] (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:9036:22)
    at ReactCompositeComponentWrapper._renderValidatedComponentWithoutOwnerOrContext (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22776:28)
    at ReactCompositeComponentWrapper._renderValidatedComponent (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22802:24)
    at ReactCompositeComponentWrapper._updateRenderedComponent (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22728:30)
    at ReactCompositeComponentWrapper._performComponentUpdate (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22708:6)
    at ReactCompositeComponentWrapper.updateComponent (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22627:6)
    at ReactCompositeComponentWrapper.receiveComponent (http://hostserver/index.ios.bundle?platform=ios&dev=true&hot=true:22527:6)

Upvotes: 0

Views: 1486

Answers (2)

camiblanch
camiblanch

Reputation: 4072

If you want a solution that has batch geocoding built in you could try a service like the SmartyStreets US Street Address API. Currently, there is also an International Street Address API, but it doesn't offer batch built in. You can read more about it here

Disclaimer: I work for SmartyStreets

Upvotes: 0

Bergi
Bergi

Reputation: 664297

As suggested in the comments, the geocode API might not support concurrent requests. Try to batch them:

async getLocations(locations) {
  Geocoder.fallbackToGoogle(GEOCODE_API_KEY);
  const annotations = []
  for (const l of locations) {
    const r = await this.getLocation(l)
    if (r == null) continue; // or display error message or whatever
    annotations.push(r)
    this.setState({annotations}); // move this after the loop if you want only one update
  }
}

Upvotes: 1

Related Questions