Nil
Nil

Reputation: 79

react-native get address from lon lat not displaying

I'm trying to get address from longitude and latitude. Here's what I have so far :

 getAddress(lat, long){
    let apiKey = 'myKey'
    fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${lat},${long}&key=${apiKey}`)
    .then((response) => response.json())
    .then((responseJson) => {
        const address = responseJson.results[0].formatted_address;
        return address;
    });   
  }

I get the right address but when I want to display it, it is not working :

renderItem = ({ item }) => (
     <View>
        <Text style={styles.address}>{this.getAddress(item.user.latitude, item.user.longitude)}</Text>
     </View>
  )

What am I doing wrong ?

Upvotes: 0

Views: 132

Answers (3)

Dhaval Jardosh
Dhaval Jardosh

Reputation: 7299

Using the state change instead,

componentWillMount(){
this.getAddress(lat,long);
}

getAddress(lat, long){
    let apiKey = 'myKey'
    fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${lat},${long}&key=${apiKey}`)
    .then((response) => response.json())
    .then((responseJson) => {
        const address = responseJson.results[0].formatted_address;
        this.setState({address})
    });   
  }


renderItem = ({ item }) => (
     <View>
        {this.state.address ? 
              this.state.address.map(singleAddress => 
                  <Text style={styles.address}>{singleAddress}</Text>) 
                : <Text>Loading Data</Text>
        }
     </View>
  )

Initially this.state.address will be empty so nothing will be displayed, but as soon as you get a value from fetch, it will update the state and upon a change of state, it will re-render and show the correct data.

YOUR WILL VIEW THE BELOW RESULT ON THE SCREEN

This is the result of "address"

enter image description here

PLAYGROUND:

class App extends React.Component {
  state = {
    address: 'default address, please add API KEY'
  }

  componentWillMount() {
    this.getAddress(40.341, -109.231); //PUT YOUR LOCATION CO-ORDINATES
  }

  //
  getAddress(lat, long) {
    let apiKey = 'myKey' //Make Sure to add your API KEY
    fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${lat},${long}&key=${apiKey}`)
      .then((response) => response.json())
      .then((responseJson) => {
        console.log(responseJson.results[0].formatted_address)
        const address = responseJson.results[0].formatted_address;
        this.setState({
          address
        });
      });
  }
  render() {
    return <p > {
      this.state.address
    } < /p>
  }
}

ReactDOM.render( < App / > , document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>

Upvotes: 1

iambinodstha
iambinodstha

Reputation: 1007

you can callback your asynchronous response and use it.

getAddress(lat, long, callback){
    let apiKey = 'myKey'
    fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${lat},${long}&key=${apiKey}`)
    .then((response) => response.json())
    .then((responseJson) => {
        const address = responseJson.results[0].formatted_address;
        callback(address);
    });   
  }

renderItem = ({ item }) => (
<View>
 {
  this.getAddress(item.user.latitude, item.user.longitude, (value)=><Text
  style={styles.address}
  >{value}</Text>)
 }
</View>
)

Upvotes: 2

Kraylog
Kraylog

Reputation: 7553

fetch is an asynchronous call, which returns a Promise. This is why to get the value out of the response you use the Promise's then clause. However, the function getAddress does not return the promise. In fact, it returns undefined.

The return keyword in the then clause only returns a new value to be wrapped by the new Promise.

To get this to work you need to return the promise from the function:

return fetch(...)

And then to use the value that is returned, you can then, again, only use the then clause, since this is asynchronous. So in fact, renderItem becomes asynchronous as well:

renderItem = ({ item }) => {
    return this.getAddress(item.user.latitude, item.user.longitude)
      .then(address => (
        <View>
          <Text style={styles.address}>{address}</Text>
        </View>
      ));

Upvotes: 0

Related Questions