React native fetch multi markers [Unhandled promise rejection:TypeError:TypeError:undefined不是对象(评估'this.state.markers.map

时间:2018-04-09 21:10:39

标签: react-native

我尝试从Google Places(nearbysearch)API获取数据,然后根据我所做的查询返回JSON中的位置列表对象。我只是想处理这些对象并获取它们的纬度和经度值,并将它们标记为要在MapView中渲染和返回的标记,这是我到目前为止所做的。 (请原谅我的杂乱代码,因为这是我第一次尝试这样做并第一次尝试一下)。

export default class Whereto extends Component<{}> {

constructor(props) {
    super(props);

this.state = {
    latitude: null,
    longitude: null,
    location: null,
    error: null,
    markers:[
        {latlng: {latitude: null, longitude: null}}
    ]
};
}

然后我使用地理位置库来查找我当前的位置,稍后将其用作对附近场地API的查询

componentDidMount() {
        navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                    error: null,
                });

            var myApiKey = '';

            fetch('https://maps.googleapis.com/maps/api/geocode/json?address=' + position.coords.latitude + ',' + position.coords.longitude + '&key=' + myApiKey)
                .then((response) => response.json())
                .then((responseJson) => {
                    //console.log('ADDRESS GEOCODE is BACK!! => ' + JSON.stringify(responseJson));
                   .... .....
                }) this section is not the complete code but it is working which is simply used to return my current location

在我的componentdidMount()函数下面是对Google Places附近搜索(API)的提取

var apiPlaceskey = '';
                //https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=-33.8670522,151.1957362&radius=500&type=restaurant&keyword=cruise&key=YOUR_API_KEY



fetch('https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=' + position.coords.latitude + ',' + position.coords.longitude + '&radius=500&type=bus_station&key=' + apiPlaceskey)
                .then((respplaces) => respplaces.json())
                .then((responseJson2) => {
                    //console.log(JSON.stringify(responseJson2));
                    //var locationName = responseJson.results[0].address_components.filter(x => x.types.filter(t => t === 'administrative_area_level_2').length > 0)[0].short_name;
                    for (var i = 0, length = responseJson2.length; i < length; i++){
                        var data = json[i],
                           latlng = (responseJson2.results[0].geometry.location.lat, responseJson2.results[0].geometry.location.lng);
                    }
                this.setState({
                    markers: latlng
                })

似乎API调用成功,因为我得到了一个返回,这是一个示例..

{
  "html_attributions": [],
  "results": [
    {
      "geometry": {
        "location": {
          "lat": 52.90050499999999,
          "lng": -1.478267
        },
        "viewport": {
          "northeast": {
            "lat": 52.90185398029149,
            "lng": -1.476918019708498
          },
          "southwest": {
            "lat": 52.89915601970849,
            "lng": -1.479615980291502
          }
        }
      },
      "icon": "https://maps.gstatic.com/mapfiles/place_api/icons/bus-71.png",
      "id": "4e992af207c8ff3503999574d25155ccf9b48f70",
      "name": "Randolph Road",
      "place_id": "ChIJM0syu93weUgRXSKhX6Flay8",
      "reference": "CmRRAAAAaE7cMbH9gq0w1U18RFtzX1GsEjTb7G2msTt4sL1hnvb5DrwTpFyznlVc9TvlfkOSkmJwU-dMa_RAvTO_8hCe_FeGIpQjwxMs7izIMg_oWYtGyzu9jQ0aIL9a_dRO40KvEhCrcpisZYRNNpDJH6p31oa6GhQpwF8PSkltIQvmsLMabEAnJWQ3OA",
      "scope": "GOOGLE",
      "types": [
        "bus_station",
        "transit_station",
        "point_of_interest",
        "establishment"
      ],
      "vicinity": "United Kingdom"
    },
    {
      "geometry": {
        "location": {
          "lat": 52.900963,
          "lng": -1.478217
        },
        "view ........
and here comes my render section.

render(){

        return(
            <View style={styles.container}>
                <Mainlogo/>

                <MapView style={styles.map}>

                    <MapView.Marker
                        coordinate={{
                            latitude: this.state.latitude,
                            longitude: this.state.longitude,
                            latitudeDelta: 0.02,
                            longitudeDelta: 0.02
                        }}
                        image={require('../img/my-pin-512.png')}
                        title={'you are here'}
                    />

                    {this.state.markers.map(marker => (
                        <MapView.Marker
                            coordinate={marker.latlng}
                        />

                    ))}

                </MapView>
            </View>
        )
    }
}

经过多次调整并在网上修改和搜索我没有运气,并继续收到此错误:

[Unhandled promise rejection: TypeError: TypeError: undefined is not an object (evaluating 'this.state.markers.map')] 22:23:24 ▼Warning: Failed prop type: The prop coordinate.latitude is marked as required in MapMarker, but its value is null.

enter image description here

enter image description here

新错误

2 个答案:

答案 0 :(得分:1)

我认为这是你要做的...用lat / long创建一个新数组并将其设置为标记。用这个替换你的循环和setState:

const markers = responseJson2.results.map((result) => ({
  latlng: {
    latitude: result.geometry.location.lat,
    longitude: result.geometry.location.lng,
  }
});

this.setState({ markers });

答案 1 :(得分:0)

乍一看,这看起来像是一个异步问题。

您的render方法未检查未定义的值。 这是我正在谈论的部分:

{this.state.markers.map(marker => (
  // ...
))}

在您的获取请求具有结果之前,将调用render方法。但是,当时不会填充this.state.markers

您应该添加某种占位符视图,该视图可以在google api返回结果之前显示。

这样的事情:

render() {
  if (myContrivedCondition) return <View styles={styles.placeholder}/>;

  // your render code
}

一旦响应到达,它将因您的this.setState而触发组件更新。

希望这有帮助。