反应本机axios嵌套api调用

时间:2018-03-22 20:06:25

标签: reactjs api react-native promise axios

我正在进行两次API调用,一次接收地址并给出lat和long坐标。第二个应该执行功能n.1设置状态并使用那些坐标并显示我附近的餐馆。

我将FetchRestaurants()附加到按钮上,当我点击它时,我注意到第一个功能已执行,但我必须双击才能使第二部分运行,这是我的主要问题。

非常感谢任何帮助。感谢你们!

这是我的2个功能

  //api call - takes address and sets coordinates in state
  FetchCords = (address)  => {
    const apiKey = "kk";
    const urlPath = `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${apiKey}`;
     axios.get(urlPath)
      .then(response => {
        const latitude = response.data.results[0].geometry.location.lat;
        const longitude = response.data.results[0].geometry.location.lng;
        this.setState({ latitude, longitude });
      })
      .catch(error => {
        console.log(error);
      });
  }


  //gets an array of restaurants
  fetchRestaurants =() => {
   this.FetchCords(this.state.address);

    const apiKey = "yy";
    let coordinates = `${this.state.latitude},${this.state.longitude}`;
    const urlPath = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${coordinates}&radius=500&type=restaurant&key=${apiKey}`;

    axios.get(urlPath)
      .then(response => {
        const restaurants = response.data.results;
        this.setState({ restaurants });
      })
      .catch(error => {
        console.log(error);
      });
  }

我还尝试同时运行两个调用,如axios docs中所述。我仍然需要手动点击2次以获得预期的最终结果。

  //api call - takes address and sets coordinates in state
  FetchCords = (address)  => {
    const apiKey = "kk";
    const urlPath = `https://maps.googleapis.com/maps/api/geocode/json?address=${address}&key=${apiKey}`;
     return axios.get(urlPath)

  }
  //gets an array of restaurants
  fetchRestaurants =() => {
    // this.FetchCords(this.state.address);

    const apiKey = "yy";
    let coordinates = `${this.state.latitude},${this.state.longitude}`;
    const urlPath = `https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=${coordinates}&radius=500&type=restaurant&key=${apiKey}`;

    return axios.get(urlPath)

  }

  onClickFetch(){
    axios.all([this.FetchCords(this.state.address), this.fetchRestaurants()])
  .then(axios.spread((coordinateFetch, restaurantFetch) => {
    // Both requests are now complete
    // console.log(coordinateFetch.data.results[0])
          // .then(response => {
        const latitude = coordinateFetch.data.results[0].geometry.location.lat;
        const longitude = coordinateFetch.data.results[0].geometry.location.lng;
        this.setState({ latitude, longitude });
        const restaurants = restaurantFetch.data.results;
        this.setState({ restaurants });

      // .catch(error => {
      //   console.log(error);
      // });
  }));
  }

这是我的渲染方法

render() {
    return (
      <View style={styles.container}>
        <View style={styles.v2}>
          <TextInput
            style={styles.txtPosition}
            onChangeText={address => this.setState({ address })}
          />
          <Button
            color={"red"}
            title="Search"
            onPress={this.onClickFetch}
          />
        </View>

        <View style={styles.v1}>
          {/* <Button color="black" title="Test" onPress={this.renderMarker} /> */}

          <MapView
            style={styles.mapStyle}
            initialRegion={{
              latitude: 60.200692,
              longitude: 24.934302,
              latitudeDelta: 0.0322,
              longitudeDelta: 0.0221
            }}
            customMapStyle={mapStyle}
          >
            {this.state.restaurants.map((marker, index) => (
              <MapView.Marker
                key={index}
                coordinate={{
                  latitude: marker.geometry.location.lat,
                  longitude: marker.geometry.location.lng
                }}
                title={marker.name}
                description={marker.vicinity}
              />
            ))}
          </MapView>
        </View>
      </View>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

您的第二个API调用取决于第一次API调用的结果,您必须在启动第二次API调用之前等待API响应。您可以使用Promise来实现此目的。

FetchCords = (address) => {
  return new Promise((resolve, reject) => {
    /* set url as per ur need */
    const url = ...
    asiox.get(url).then((response) => {
      resolve({
        lat: response.data.results[0].geometry.location.lat,
        long: response.data.results[0].geometry.location.lng
      });
    }).catch(err => reject(err));
  });
}

fetchRestaurants = () => {
  FetchCords(this.state.address).then((cord) => {
    axios.get(/*use the `cord.lat and cord.long` */)
    .then(response => {
      const restaurants = response.data.results;
      this.setState({ restaurants });
    }).catch(() => {
      /* do whatever u want*/
    });
  }).catch(() => {
    /* do whatever u want*/
  });
}

希望这会有所帮助。