How to get the address from google maps autocomplete in React Native
Asked Answered
D

4

6

I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it in other component.

How can I save the address

This is my code

import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};

export default class google extends Component {
  render(){

  return (
    <View style={styles.container}>
      <View style={styles.top}>
    <GooglePlacesAutocomplete
      placeholder='Search'
      minLength={2} // minimum length of text to search
      autoFocus={false}
      returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
      listViewDisplayed='auto'    // true/false/undefined
      fetchDetails={true}
      renderDescription={row => row.description} // custom description render
      onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);
        this.setState(
                  {
                    address: data.description, // selected address
                    coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
                  }
                );
      }}

      getDefaultValue={() => ''}

      query={{
        // available options: https://developers.google.com/places/web-service/autocomplete
        key: 'AIzaS#################',
        language: 'es', // language of the results

      }}

      styles={{
        textInputContainer: {
          width: '100%'
        },
        description: {
          fontWeight: 'bold'
        },
        predefinedPlacesDescription: {
          color: '#1faadb'
        }
      }}

      currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
      currentLocationLabel="Current location"
      nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
      GoogleReverseGeocodingQuery={{
        // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
      }}
      GooglePlacesSearchQuery={{
        // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
        rankby: 'distance',
        types: 'food'
      }}

      filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
      predefinedPlaces={[homePlace, workPlace]}

      debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
      renderRightButton={() => <Text>Custom text after the input</Text>}
    />
    </View>
    <View style={styles.container2}>
      <Text>
        hola {this.setState.address}
      </Text>
    </View>
    </View>

  );
}
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
  width: '100%',
height: '100%',

  },
  welcome: {
    fontSize: 40,
    textAlign: 'center',
    margin: 10,
color:'black',
  },
  instructions: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
  },
top: {
height: '50%',
justifyContent: 'center',
    alignItems: 'center',
  },

container2: {
   height:'75%',
   justifyContent: 'center',
  },
buttonContainer: {
alignItems: 'center',
    backgroundColor: 'rgba(255, 255,255, 0.5)',
    padding: 1,
    margin: 50,
    borderRadius: 25,
    borderWidth: 2,
    borderColor: '#0B0B3B'

     },
textoboton: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
    fontSize: 12

  },

})

I've been also using another library with some differences

app.js

import React,{Component} from 'react';
import { Constants } from 'expo';
import Icon from 'react-native-vector-icons/FontAwesome';
import { View, Image, Text, StyleSheet, AsyncStorage, Button,ScrollView, TextInput, ActivityIndicator } from 'react-native';
import {
  NavigationActions
} from 'react-navigation';
import { GoogleAutoComplete } from 'react-native-google-autocomplete';
import {Card, Input} from "react-native-elements";

import LocationItem from './locationItem';


export default class App extends React.Component {

  state={
    datos:[],
  }
  componentDidMount(){
    this._loadedinitialstate().done();
  }
  _loadedinitialstate =async() => {
    AsyncStorage.getItem('datos');
  }

  render() {
    return (
      <View style={styles.container}>
        <GoogleAutoComplete apiKey={'AIzaSyB2HyNTBm1sQJYJkwOOUA1LXRHAKh4gmjU'} debounce={20} minLength={2} getDefaultValue={() => ''}  onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);}}   returnKeyType={'default'} fetchDetails={true}
>
          {({
            locationResults,
            isSearching,
            clearSearchs,
            datos,
            handleTextChange
          }) => (
            <React.Fragment>
              <View style={styles.inputWrapper}>
                <Input
                  style={styles.textInput}
                  placeholder="Ingresa tu direccion"
                  onChangeText={(datos) => this.setState({datos})}
                  value={datos}
                />

              </View>
              {isSearching && <ActivityIndicator size="large" color="red" />}
             <ScrollView>
               {locationResults.map(el => (
                 <LocationItem
                   {...el}
                   key={el.id}
                 />
               ))}
             </ScrollView>
            </React.Fragment>
          )}
        </GoogleAutoComplete>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  textInput: {
    height: 40,
    width: 300,
    borderWidth: 1,
    paddingHorizontal: 16,
  },
  inputWrapper: {
    marginTop: 80,
    flexDirection: 'row'
  },
});

locationitem.js

import React, { PureComponent } from 'react';
import { View, Alert, Text, StyleSheet, TouchableOpacity, AsyncStorage} from 'react-native';

class LocationItem extends PureComponent {

  constructor(props) {
    super(props);
    this.state = {datos:''};
  }

  _handlePress = () => {
    AsyncStorage.setItem('datos',datos)
  }



  render() {
    return (
      <TouchableOpacity style={styles.root} onPress={this._handlePress}  >
        <Text value={this.state.datos}> {this.props.description} </Text>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  root: {
    height: 40,
    borderBottomWidth: StyleSheet.hairlineWidth,
    justifyContent: 'center'
  }
})

export default LocationItem;

The source of both codes is here react-native-google-places-autocomplete enter link description here

Which code will be easy to use, and How can I solve my Issue (get the address) ??

Any Answer will be Helpful

Delineation answered 18/7, 2018 at 4:32 Comment(0)
S
3

first install

npm i react-native-google-places-autocomplete

then

import React from 'react';
import { View, Image } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';

const homePlace = { description: 'Home', geometry: { location: { lat: 48.8152937, lng: 2.4597668 } }};
const workPlace = { description: 'Work', geometry: { location: { lat: 48.8496818, lng: 2.2940881 } }};

const GooglePlacesInput = () => {
  return (
    <GooglePlacesAutocomplete
      placeholder='Search'
      minLength={2} // minimum length of text to search
      autoFocus={false}
      returnKeyType={'search'} // Can be left out for default return key https://facebook.github.io/react-native/docs/textinput.html#returnkeytype
      listViewDisplayed='auto'    // true/false/undefined
      fetchDetails={true}
      renderDescription={row => row.description} // custom description render
      onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true
        console.log(data, details);
      }}

      getDefaultValue={() => ''}

      query={{
        // available options: https://developers.google.com/places/web-service/autocomplete
        key: 'YOUR API KEY',
        language: 'en', // language of the results
        types: '(cities)' // default: 'geocode'
      }}

      styles={{
        textInputContainer: {
          width: '100%'
        },
        description: {
          fontWeight: 'bold'
        },
        predefinedPlacesDescription: {
          color: '#1faadb'
        }
      }}

      currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
      currentLocationLabel="Current location"
      nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
      GoogleReverseGeocodingQuery={{
        // available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
      }}
      GooglePlacesSearchQuery={{
        // available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
        rankby: 'distance',
        types: 'food'
      }}

      filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
      predefinedPlaces={[homePlace, workPlace]}

      debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
      renderLeftButton={()  => <Image source={require('path/custom/left-icon')} />}
      renderRightButton={() => <Text>Custom text after the input</Text>}
    />
  );
}
Scholium answered 24/10, 2018 at 5:14 Comment(0)
S
2

After a long journey, these steps helped me solve the problem.

1) Install npm install react-native-google-places-autocomplete --save.

2) Then use this code below, as an element in your component.

<GooglePlacesAutocomplete
          query={{
            key: "GOOGLE_PLACES_API_KEY",
            language: "en", // language of the results
          }}
          onPress={(data, details = null) => {
            console.log(details);
            console.log(data);
            console.log("data.description",data.description.split(','));

          }}
          onFail={(error) => console.error(error)}
          listViewDisplayed="false"
          requestUrl={{
            url:
              "https://cors-                  
         anywhere.herokuapp.com/https://maps.googleapis.com/maps/api",
            useOnPlatform: "web",
          }} // this in only required for use on the web. See https://git.io/JflFv 
            more for details.
          styles={{
            textInputContainer: {
              backgroundColor: "rgba(0,0,0,0)",
              borderTopWidth: 0,
              borderBottomWidth: 0,
            },
            textInput: {
              marginLeft: 0,
              marginRight: 0,
              height: 38,
              color: "#5d5d5d",
              fontSize: 16,
            },
            predefinedPlacesDescription: {
              color: "#1faadb",
            },
          }}
        />

3) You may have the same problem that i had, which the list disappears when i try to select result. However, this is the action that solved this problem for me. Commenting out onBlur on node_modules. path: "..\node_modules\react-native-google-places-autocomplete\GooglePlacesAutocomplete.js".

    ...
    onFocus={onFocus ? () => {this._onFocus(); onFocus()} : this._onFocus}
    // onBlur={this._onBlur}
    underlineColorAndroid={this.props.underlineColorAndroid}
    ... 

4) For saving the address you can check the console.log in the code, and then use setState or something like this.

5) For more information and options of these element check out this repository: https://github.com/FaridSafi/react-native-google-places-autocomplete.

hope this will help for you :)

Silky answered 14/6, 2020 at 23:1 Comment(0)
S
1

First of all, I used listViewDisplayed={false} because otherwise the list view get stuck with the results, and even on location press the list doesn't closes.

Second, to answer your question: The results are in the onPress function of GooglePlacesAutocomplete, you can update the state with the chosen location and then use it where ever you want in your component:

onPress={(data, details = null) => {
          this.setState({
          latitude: details.geometry.location.lat,
          longitude: details.geometry.location.lng,
          moveToUserLocation: true
        });
          this._gotoLocation();
        }
      }

As i wrote it, onPress also trigger the function that moves the map to display the new location.

Seraphina answered 21/11, 2018 at 14:11 Comment(0)
W
0
import React, {Component} from 'react';
import { View, Image, Text, StyleSheet } from 'react-native';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';


export default class google extends Component {
        constructor(props) {
                super(props);
                this.state = {
                    address:null,
                    lat:null,
                    lng:null,
                }
            }

     getAdd(data){
        console.log("add",data);
        this.setState(
            {
              address: data.formatted_address, // selected address
              lat: data.geometry.location.lat,//  selected coordinates latitude
              lng:data.geometry.location.lng, //  selected coordinates longitute

            }
          );
       console.log("this.state.address",this.state.address); ///to console address
       console.log("this.state.coordinates",this.state.lat,this.state.lng); /// to console coordinates

    }


  render(){

  return (
    <View style={styles.container}>
      <View style={styles.top}>
        <GooglePlacesAutocomplete
            placeholder='Search'
            minLength={2} // minimum length of text to search
            autoFocus={false}
            fetchDetails={true}
            returnKeyType={'default'}
            onPress={(data, details = null) => { // 'details' is provided when fetchDetails = true

              var data = details;
              this.getAdd(data);
            }}
            query={{
              // available options: https://developers.google.com/places/web-service/autocomplete
              key: 'AIzaS#################',
              language: 'en',
              types: 'geocode', // default: 'geocode'
            }}

            listViewDisplayed={this.state.showPlacesList}
            textInputProps={{
              onFocus: () => this.setState({ showPlacesList: true }),
              onBlur: () => this.setState({ showPlacesList: false }),
            }}
            styles={{
                textInputContainer: {
                  width: '100%'
                },
                description: {
                  fontWeight: 'bold'
                },
                predefinedPlacesDescription: {
                  color: '#1faadb'
                }
              }}

            currentLocation={true} // Will add a 'Current location' button at the top of the predefined places list
            currentLocationLabel="Current location"
            nearbyPlacesAPI='GooglePlacesSearch' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch

            filterReverseGeocodingByTypes={['locality', 'administrative_area_level_3']} // filter the reverse geocoding results by types - ['locality', 'administrative_area_level_3'] if you want to display only cities
            // predefinedPlaces={[]}

            predefinedPlacesAlwaysVisible={true}
          />

            </View>

            { this.state.address !=null ?(
            <View style={styles.container2}>
            <Text>
                Address: {this.state.address}
            </Text>
            </View>
            ):null }
            </View>

  );
}
}

const styles = StyleSheet.create({
  container: {
  width: '100%',
height: '100%',

  },
  welcome: {
    fontSize: 40,
    textAlign: 'center',
    margin: 10,
color:'black',
  },
  instructions: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
  },
top: {
height: '50%',
justifyContent: 'center',
    alignItems: 'center',
  },

container2: {
   height:'75%',
   justifyContent: 'center',
  },
buttonContainer: {
alignItems: 'center',
    backgroundColor: 'rgba(255, 255,255, 0.5)',
    padding: 1,
    margin: 50,
    borderRadius: 25,
    borderWidth: 2,
    borderColor: '#0B0B3B'

     },
textoboton: {
    textAlign: 'center',
    color: 'black',
    marginBottom: 5,
    fontSize: 12

  },

})    
Watanabe answered 22/11, 2018 at 13:32 Comment(1)
Usually it's better to explain a solution instead of just posting some rows of anonymous code. You can read How do I write a good answer, and also Explaining entirely code-based answersPampuch

© 2022 - 2024 — McMap. All rights reserved.