PostsArt

Auto-detect location react component using google geocoding and reverse geocoding in autocomplete

You,

Auto-detect location react component using google geocoding and reverse geocoding in autocomplete

Auto detect React Component

AutoDetect : Dumb component

Make a state less component with the SVG included.

onClick handler is passed as props for this component which is defined in Higher order component (AutoComplete)

import React from "react"; import PropTypes from "prop-types"; import Navigation from "./navigation.svg";const style = { width: "14px" }; const AutoDetect = (props) => { return ( <div > <span className="Datalist\_\_item h-48 c-blue flex flex-middle fs-14" onClick={ props.onClick } > <Navigation className="Note\_\_icon mr-5" fill="#36c" style={ style } /> Current location </span> </div> ); }; AutoDetect.propTypes = { onClick: PropTypes.func }; AutoDetect.defaultProps = { onClick: null };export default AutoDetect;

AutoComplete : Pure component

We call this._renderAutoDetect() in render method of AutoComplete which in turns calls **<AutoDetect />** component described above.

We will pass onClick handler to this

<AutoDetect onClick={ this.\_detectUserLocation } />

which will be passed as prop to AutoDetect component.

**_detectUserLocation** is where we call browser object **navigator.geolocation.getCurrentPosition** which will first prompt user to allow or deny location.

Browser prompt

If it is allowed then either success or error callback is called.

Error callback

this.geoError = (error) => { switch (error.code) { case error.TIMEOUT: console.log("Browser geolocation error !\\n\\nTimeout."); break; case error.PERMISSION\_DENIED: console.log("Only secure origins are allowed"); break; case error.POSITION\_UNAVAILABLE: console.log("Browser geolocation error !\\n\\nPosition unavailable."); break; default: console.log(error.code); break; } };

Success callback

this.geoSuccess = (position) => { this.\_displayLocation(position.coords.latitude, position.coords.longitude); };

The success callback **geoSuccess** has position as parameter which contains user latitude and longitude.

Now we will call **_displayLocation** passing these lat and long for Google reverse geocoding.

Google Reverse GeoCoding

\_geocodeAddress = (geocoder, latlng) => { geocoder.geocode({ location: latlng }, this.\_geoCodeCallback); }if (navigator.geolocation) { this.\_displayLocation = (latitude, longitude) => { const geocoder = new google.maps.Geocoder(); const latlng = new google.maps.LatLng(latitude, longitude); this.\_geocodeAddress(geocoder, latlng); };

From success callback of Geocoding , we called **_displayLocation** where we will instantiate google map **Geocoder** and call **maps.Latlng**

The callback after success is **_geoCodeCallBack**

This callback will have result of different address formats fetched from passed latitude and longitude.

We can fetch city from this result.

\_geoCodeCallback = (results, status, event) => { const google = window.google; // eslint-disable-line if (status === google.maps.GeocoderStatus.OK) { if (results\[0\]) { const add = results\[0\].formatted\_address; const value = add.split(","); const count = value.length; const city = value\[count - 3\]; // here we can dispatch action to search by city name and autofill the autocomplete } else { console.log("address not found"); } } else { console.log(status); } }

Now we can dispatch an action to React Middleware or directly to store using connect to fetch the autocomplete result from the city.

const bindActionsToDispatch = dispatch => ( { searchFlightAirports: (city, meta) => { dispatch(<action\_creator name>(city, meta)); } } ); export default connect(null, bindActionsToDispatch)(Autocomplete);

Below is the entire code.

\_geoCodeCallback = (results, status, event) => { const google = window.google; // eslint-disable-line if (status === google.maps.GeocoderStatus.OK) { if (results\[0\]) { const add = results\[0\].formatted\_address; const value = add.split(","); const count = value.length; const city = value\[count - 3\]; // here we can dispatch action to search by city name and autofill the autocomplete } else { console.log("address not found"); } } else { console.log(status); } }\_geocodeAddress = (geocoder, latlng) => { geocoder.geocode({ location: latlng }, this.\_geoCodeCallback); }\_detectUserLocation = (event) => { // check for Geolocation support const google = window.google; // eslint-disable-lineif (navigator.geolocation) { this.\_displayLocation = (latitude, longitude) => { const geocoder = new google.maps.Geocoder(); const latlng = new google.maps.LatLng(latitude, longitude); this.\_geocodeAddress(geocoder, latlng); };this.geoSuccess = (position) => { this.\_displayLocation(position.coords.latitude, position.coords.longitude); };this.geoError = (error) => { switch (error.code) { case error.TIMEOUT: console.log("Browser geolocation error !\\n\\nTimeout."); break; case error.PERMISSION\_DENIED: console.log("Only secure origins are allowed"); break; case error.POSITION\_UNAVAILABLE: console.log("Browser geolocation error !\\n\\nPosition unavailable."); break; default: console.log(error.code); break; } }; navigator.geolocation.getCurrentPosition(this.geoSuccess, this.geoError); } else { console.log("Geolocation is not supported for this Browser/OS."); } }\_renderAutoDetect = () => { return ( <AutoDetect onClick={ this.\_detectUserLocation } /> ); }render() { return ( <div className="Autocomplete"> <Input autoFocus={ this.props.autoFocus } focusDelay={ this.props.focusDelay } name="autocomplete" inputClassName="Autocomplete\_\_search mb-0" value={ this.props.value } onChange={ this.\_handleChange } autoComplete="off" placeholder={ this.props.placeHolder } /> this.\_renderAutoDetect() </div> ); } }

Note: You will need to create Google API map key and include that in your website layout file.

© Eesh Tyagi.RSS