React-native-maps: this.setState is not a function in onRegionChange and onRegionChangeComplete

Created on 4 Jun 2016  路  1Comment  路  Source: react-native-maps/react-native-maps

Hey guys I'm just getting started and have an example running showing a map and markers from my api. But when I add onRegionChange and onRegionChangeComplete functions like in the examples I am getting this.setState is not a function errors from within those two functions. Any help would be appreciated. Here is the entirety of index.ios.js. It's basically the getting started app with some api and mapview code added in...

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Dimensions
} from 'react-native';

import MapView from 'react-native-maps';

var REQUEST_URL = 'http://127.0.0.1:8000/api/location/';

var { width, height } = Dimensions.get('window');

const ASPECT_RATIO = width / height;
const LATITUDE = -37.791108;
const LONGITUDE = 175.28016;
const LATITUDE_DELTA = 0.0922;
const LONGITUDE_DELTA = LATITUDE_DELTA * ASPECT_RATIO;

class GassyApp extends Component {
  constructor(props) {
    super(props);
    this.state = {
      region: {
        latitude: LATITUDE,
        longitude: LONGITUDE,
        latitudeDelta: LATITUDE_DELTA,
        longitudeDelta: LONGITUDE_DELTA,
      },
      markers: [],
      loaded: false
    };
  }

  componentDidMount() {
    console.warn('componentDidMount');
    navigator.geolocation.getCurrentPosition(
      (position) => {
        console.warn(position);
        var region = {
          latitude: position.coords.latitude,
          longitude: position.coords.longitude,
          latitudeDelta: LATITUDE_DELTA,
          longitudeDelta: LATITUDE_DELTA * ASPECT_RATIO,
        };
        this.setState({region});
      },
      (error) => alert(error.message),
      {enableHighAccuracy: true, timeout: 20000, maximumAge: 1000}
    );

    this.watchID = navigator.geolocation.watchPosition((position) => {
      var region = {
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        latitudeDelta: LATITUDE_DELTA,
        longitudeDelta: LATITUDE_DELTA * ASPECT_RATIO,
      };
      this.setState({region});
    });

    this.fetchData();
  }

  componentWillUnmount() {
    navigator.geolocation.clearWatch(this.watchID);
  }

  fetchData() {
    console.warn('fetchData')
    fetch(REQUEST_URL + this.getBoundsUrl())
      .then((response) => response.json())
      .then((responseData) => {
        /**
         * Example response:
         * {
         *   "type":"FeatureCollection",
         *   "features":[
         *     {"id":79,
         *      "type":"Feature",
         *      "geometry":{
         *        "type":"Point",
         *        "coordinates":[175.28016,-37.791108]},
         *        "properties":{"country_code":"NZ","gisprecision":"manual"}
         *      }
         *    ]
         *  }
        */

        var markers = [];
        for (var i = 0; i < responseData.features.length; i++) {
          var coords = responseData.features[i].geometry.coordinates;
          var marker = {
            key: responseData.features[i].id,
            coordinate: {
              latitude: coords[1],
              longitude: coords[0],
            }
          }
          markers.push(marker);
        }

        this.setState({
          markers: markers,
          loaded: true,
        });
      })
      .done();
  }

  onRegionChange(region) {
    console.warn('onRegionChange')
    this.setState({ region });
  }

  onRegionChangeComplete(region) {
    console.warn('onRegionChangeComplete')
    this.setState({ region });
    this.fetchData();
  }

  getBoundsUrl() {
    console.warn('getBoundsUrl')
    var region = this.state.region;
    var minLon = region.longitude + (region.longitudeDelta / 2.0);
    var minLat  = region.latitude  - (region.latitudeDelta  / 2.0);
    var maxLon = region.longitude - (region.longitudeDelta / 2.0);
    var maxLat  = region.latitude  + (region.latitudeDelta  / 2.0);

    var bbox = "?in_bbox=" + minLat + "," + minLon + "," + maxLat + "," + maxLon;

    return bbox;
  }

  render() {
    if (!this.state.loaded) {
      return this.renderLoadingView();
    }

    return (
      <View style={styles.container}>
        <MapView
          style={styles.map}
          region={this.state.region}
          onRegionChange={this.onRegionChange}
          onRegionChangeComplete={this.onRegionChangeComplete}
          showsUserLocation={true}
          followUserLocation={true}
        >
          {this.state.markers.map(marker => (
            <MapView.Marker
              key={marker.key}
              coordinate={marker.coordinate}
            />
          ))}
        </MapView>
      </View>
    );
  }

  renderLoadingView() {
    return (
      <View style={styles.container}>
        <Text>
          Loading...
        </Text>
      </View>
    );
  }
}

var styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    justifyContent: 'flex-end',
    alignItems: 'center',
  },
  map: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
  },
});

AppRegistry.registerComponent('GassyApp', () => GassyApp);

Most helpful comment

@carlosfunk There is no auto binding when using es7 class. Here are a ways you can do it.

onRegionChange = (region) => {}

onRegionChange={::this.onRegionChange}
onRegionChange={() => this.onRegionChange.bind(this)}

More info: http://www.ian-thomas.net/autobinding-react-and-es6-classes/

>All comments

@carlosfunk There is no auto binding when using es7 class. Here are a ways you can do it.

onRegionChange = (region) => {}

onRegionChange={::this.onRegionChange}
onRegionChange={() => this.onRegionChange.bind(this)}

More info: http://www.ian-thomas.net/autobinding-react-and-es6-classes/

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Anandks1993 picture Anandks1993  路  3Comments

tnrich picture tnrich  路  3Comments

iSimar picture iSimar  路  3Comments

rafetkhallaf picture rafetkhallaf  路  3Comments

KarlosQ picture KarlosQ  路  3Comments