Current Location in react-native-google-places-autocomplete - react-native

When the current location is selected, the api gets the locations but the list seems to be not populating/displaying the places.
But when selected it does reverse geocode and print the details in the console.
However it does not get set to the textInput.
Not sure what I am missing
This is how the screen looks like
The code look like this
<GooglePlacesAutocomplete
placeholder='Deliver To'
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 || row.vicinity} // 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: '',
language: 'en', // language of the results
types: 'geocode', // default: 'geocode'
components: 'country:au',
}}
styles={{
textInputContainer: {
width: '100%',
backgroundColor: 'rgba(0,0,0,0)',
borderLeftWidth: 0.5,
borderRightWidth: 0.5,
},
textInput: {
fontFamily: "AvenirMedium",
fontSize: 17,
color: "#000",
backgroundColor: 'rgba(0,0,0,0)',
},
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={'GoogleReverseGeocoding'} // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
GoogleReverseGeocodingQuery={{
// available options for GoogleReverseGeocoding API : https://developers.google.com/maps/documentation/geocoding/intro
key: '',
language: 'en',
}}
/>

1. Just add textInputProps={{ onBlur: () => {} }} in <GooglePlacesAutocomplete />
Ex.
2. comment // renderDescription={(row) => row.description}
`<View>
<ScrollView keyboardShouldPersistTaps="handled">
<View keyboardShouldPersistTaps="handled" >
<GooglePlacesAutocomplete
currentLocation={true}
placeholder='Enter your location'
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
keyboardAppearance={'light'} // Can be left out for default keyboardAppearance https://facebook.github.io/react-native/docs/textinput.html#keyboardappearance
listViewDisplayed='true' // true/false/undefined
fetchDetails={true}
//renderDescription={row => row.description || row.formatted_address || row.name}
// renderDescription={(row) => row.description} // custom description render
//components='country:ind'
onPress={(data, details = null) => {
//let address = details.formatted_address.split(', ');
console.log("DATAA", data);
console.log("details", details.name + ", " + details.formatted_address);
if (data && details) {
this.setState({
disLocation: data.description ? data.description : details.name + ", " + details.formatted_address,
lat: details.geometry.location.lat ? details.geometry.location.lat : data.geometry.location.lat,
lng: details.geometry.location.lng ? details.geometry.location.lng : data.geometry.location.lng
})
}
}}
nearbyPlacesAPI='GooglePlacesSearch'
GooglePlacesSearchQuery={{
// available options for GooglePlacesSearch API : https://developers.google.com/places/web-service/search
rankby: 'distance',
// type: 'cafe'
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaSyCK9195rpO4FJm0UvXImv28Dek6iEBHI4k',
//language: 'fr', // language of the results
//types: 'address', // default: 'geocode'
// components: 'country:ca' // added manually
}}
styles={{
textInputContainer: {
width: '100%'
},
description: {
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
textInputProps={{ onBlur: () => {} }}
//GooglePlacesDetailsQuery={{ fields: 'formatted_address' }}
GooglePlacesDetailsQuery={{ fields: ['geometry', 'formatted_address'] }}
debounce={300} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
/>
</View>
</ScrollView>
</View>`
`https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/496#issuecomment-606272340`

Related

In react-native-autocomplete-dropdown, using 2 dropdowns only 1 visible at a time (user toggles view), only onChangeText of 1st dropdown is firing

Context:
In a single screen view, there are 2 dropdowns (made using react-native-autocomplete-dropdown) but only 1 is visible at a time. The other dropdown comes into view when the user toggles the next tab. I am using react hooks and the component is a functional component. Also, I am new to react hooks.
Issue:
When I try to search on the 2nd dropdown, I expect the onChangeText function of the 2nd dropdown to fire but it fires the function of the 1st dropdown.
Source arrays:
const allYards = [{ id: "1", name: "Java" }, { id: "2", name: "React" }, { id: "3", name: "Angular" }];
const [yards, setYards] = useState(allYards);
const allTrucks = [{id: "1", name: "Truck 1"}, {id: "2", name: "Truck 2"}, {id: "3", name: "Truck 3"}]
const [trucks, setTrucks] = useState(allTrucks);
Render View code:
<View style={[styles.cardWrap, { padding: 30 }]}>
{assignTo === 'yard' ?
<>
<View style={[styles.inputGrp, { marginBottom: 30 }]}>
<Text style={[styles.inputLabel]}>Yard</Text>
<AutocompleteDropdown
ref={selectYardRef}
controller={(controller) => {
dropdownController.current = controller
}}
inputHeight={44}
debounce={600}
dataSet={yards.map((m) => ({
id: m.id,
title: m.name,
}))}
onChangeText={searchYards}
useFilter={false}
onSelectItem={(item) => {
console.log('selectedYard', item);
if (item?.id) {
setSelectedYard(item.id);
}
}}
textInputProps={{
placeholder: 'Choose the yard',
style: styles.autoInput,
}}
inputContainerStyle={styles.autoInputContainer}
containerStyle={{}}
rightButtonsContainerStyle={{
backgroundColor: '#fff',
}}
ClearIconComponent={<IconClear />}
ChevronIconComponent={<IconCaret />}
showChevron={true}
onClear={() => {
setSelectedYard(undefined);
}}
onFocus={handleOnFocus}
renderItem={(item, text) => (
<Text style={{ color: '#000', padding: 15 }}>
{`${item.title}`}
</Text>
)}
ItemSeparatorComponent={() => null}
/>
</View>
<View style={[styles.inputGrp]}>
<Text style={[styles.inputLabel]}>Address</Text>
<Text style={[styles.labelValue, { width: '50%' }]}>
123 Name Street
City, ST 00000
</Text>
</View>
</>
:
<View style={[styles.inputGrp, { marginBottom: 30 }]}>
<Text style={[styles.inputLabel]}>Truck</Text>
<AutocompleteDropdown
ref={selectTruckRef}
controller={(controller) => {
dropdownController.current = controller
}}
inputHeight={44}
debounce={600}
dataSet={trucks.map((m) => ({
id: m.id,
title: m.name,
}))}
onChangeText={searchTrucks}
useFilter={false}
onSelectItem={(item) => {
console.log('selectedYard', item);
if (item?.id) {
setSelectedTruck(item.id);
}
}}
textInputProps={{
placeholder: 'Choose the truck',
style: styles.autoInput,
}}
inputContainerStyle={styles.autoInputContainer}
containerStyle={{}}
rightButtonsContainerStyle={{
backgroundColor: '#fff',
}}
ClearIconComponent={<IconClear />}
ChevronIconComponent={<IconCaret />}
showChevron={true}
onClear={() => {
setSelectedTruck(undefined);
}}
onFocus={handleOnFocus}
renderItem={(item, text) => (
<Text style={{ color: '#000', padding: 15 }}>
{`${item.title}`}
</Text>
)}
ItemSeparatorComponent={() => null}
/>
</View>}
</View>
On change handler functions:
const searchTrucks = (searchText: string) => {
console.log("[~]Inside searchTrucks...");
if(searchText){
const regex = new RegExp(searchText, 'i');
const filteredTrucks = trucks.filter(truck => regex.test(truck.name));
setTrucks(filteredTrucks.slice(0, 5)); //Show only 1st 5 matches.
}
else{
setTrucks(allTrucks);
}
}
const searchYards = (searchText: string) => {
console.log("[~]Inside searchYards...");
if(searchText){
const regex = new RegExp(searchText, 'i');
const filteredYards = yards.filter(yard => regex.test(yard.name));
setYards(filteredYards.slice(0, 5)); //Show only 1st 5 matches.
}
else{
setYards(allYards);
}
}

Current Location issue in react-native-google-places-autocomplete

I am using react-native-google-places-autocomplete to get places suggestions based on user's current location. And it is working fine but the only issue I am facing is that whenever the 'Current Location' button is clicked, it sets the input field with value 'Current Location' and then shows the location results in the form of the list below it.
I don't want it to set currentLocationLabel value in the input field.
Here's my Code:
import React from 'react';
import { GooglePlacesAutocomplete } from 'react-native-google-places-autocomplete';
navigator.geolocation = require('#react-native-community/geolocation');
const LocationAutocompleteScreen = props => {
return (
<GooglePlacesAutocomplete
placeholder='Search Location...'
minLength={3}
autoFocus={true}
returnKeyType={'search'}
listViewDisplayed='auto'
fetchDetails={true}
onPress={(data, details = null) => {
const locParam = {
description: data.description,
placeId: data.place_id,
location: details.geometry.location
}
props.navigation.navigate('LocationSearch', {locParam} )
}}
getDefaultValue={() => {
return '' // text input default value
}}
query={{
key: 'API_KEY',
language: 'en',
components: 'country:in',
}}
styles={{
textInputContainer: {
backgroundColor: '#fff',
borderTopWidth: 0,
borderBottomWidth: 0,
marginTop: 16,
marginHorizontal: 16
},
textInput: {
marginLeft: 0,
marginRight: 0,
padding: 8,
minHeight: 30,
color: '#000000',
fontSize: 16,
fontWeight: 'bold'
},
predefinedPlacesDescription: {
color: '#1faadb',
},
listView: {
paddingHorizontal: 8
},
description: {
fontWeight: '700',
letterSpacing: 0.5,
color: '#5d5d5d'
}
}}
currentLocation={true}
currentLocationLabel='Current Location'
nearbyPlacesAPI='GoogleReverseGeocoding' // Which API to use: GoogleReverseGeocoding or GooglePlacesSearch
//renderDescription={row => row.description || row.formatted_address || row.name}
// 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
/>
);
}
export default LocationAutocompleteScreen;

How to customize the column title style in Details list

How can I change the font size and padding of the title cell in details list. I am using onRenderDetailsHeader prop to customize header render.
private renderDetailsHeader = (detailsHeaderProps: IDetailsHeaderProps) => {
return (
<DetailsHeader
{...detailsHeaderProps}
onRenderColumnHeaderTooltip={this.renderCustomHeaderTooltip}
/>
);
}
private renderCustomHeaderTooltip = (tooltipHostProps: ITooltipHostProps) => {
return (
<span
style={{
display: "flex",
fontFamily: "Tahoma",
fontSize: "10px",
justifyContent: "left",
paddingLeft: '0 px'
}}
>
{tooltipHostProps.children}
</span>
);
}
Codepen
In IDetailsHeaderProps['columns'] or simply IColumn[] => IColumn has 'headerClassName' key where you can specify the necessary styles to each of the column.
You can use the IDetailsColumnStyles interface to style the header cells.
Example:
...
const headerStyle: Partial<IDetailsColumnStyles> = {
cellTitle: {
color: theme.palette.orange,
}
}
const columns: IColumn[] = [
{ styles: headerStyle, key: 'name', name: 'Name', fieldName: 'name', minWidth: 100,},
...
Style the Row:
...
const renderRow: IDetailsListProps['onRenderRow'] = props => {
const rowStyles: Partial<IDetailsRowStyles> = {
root: {
borderBottomColor: theme.semanticColors.buttonBorder,
fontSize: theme.fonts.medium.fontSize,
},
cell: { paddingLeft: 0, },
}
if (!props) return null
return <DetailsRow {...props} styles={rowStyles} />
}
return (
<DetailsList
compact
items={items}
columns={columns}
selectionMode={SelectionMode.none}
layoutMode={DetailsListLayoutMode.justified}
constrainMode={ConstrainMode.horizontalConstrained}
onRenderRow={renderRow}
onRenderDetailsHeader={renderHeader}
onRenderItemColumn={renderItemColumn}
setKey="set"
ariaLabelForSelectionColumn="Toggle selection"
ariaLabelForSelectAllCheckbox="Toggle selection for all items"
checkButtonAriaLabel="Row Checkbox"
/>
)
...

How to select a single radio button at a time in react native flatlist

I am using react-native-radio-button to implement a flatlist with radio button as shown in the image.
[![enter image description here][1]][1]
But i am unable to select a single radio button at a time in flatlist.
Here is my code
import React from 'react';
import { StyleSheet, View, Text, FlatList, TouchableOpacity, Image, LayoutAnimation, UIManager, Platform } from 'react-native';
import RadioButton from 'react-native-radio-button';
import PHARMACY from './api/mockPharmacyList';
import { Colors, Fonts } from '../../styles';
interface IState {
selected: number;
selectedIndex: number;
data: any;
expanded: boolean;
checked: boolean;
}
export class TransferToPharmacy extends React.Component<{}, IState> {
constructor(props) {
super(props);
this.state = {
data: PHARMACY,
selected: 0,
selectedIndex: 0,
expanded: true,
checked: false,
};
this.onPress = this.onPress.bind(this);
this.renderItem = this.renderItem.bind(this);
this.renderSeparator = this.renderSeparator.bind(this);
this._keyExtractor = this._keyExtractor.bind(this);
this.changeLayout = this.changeLayout.bind(this);
this.onCheck = this.onCheck.bind(this);
if (Platform.OS === 'android') {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
changeLayout = () => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
this.setState({ expanded: false });
}
getInitialState() {
return {
value: 0,
};
}
onPress(value) {
this.setState({ selected: value });
}
_keyExtractor = (item, index) => item.id;
onCheck = () => {
const { checked } = this.state;
if (checked === true) {
this.setState({ checked: false });
} else {
this.setState({ checked: true });
}
}
renderItem(data) {
const { item } = data;
return (
<View style={styles.itemBlock}>
<TouchableOpacity >
<View style={styles.arrowIconStyle}>
<Text style={styles.pharmacyText}>{item.name}</Text>
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selectedIndex === 0}
onPress={this.onPress}
/>
</View>
</TouchableOpacity>
<Text>{item.key1}</Text>
<View style={{ height: this.state.expanded === true ? 90 : 0, overflow: 'hidden' }}>
<View style={{ flexDirection: 'row', marginTop: 5, padding: 10 }}>
<Image style={[styles.itemImage, { width: 15, height: 15, margin: 1 }]} source={require('./images/map_pic_icon.png')} />
<Text style={styles.itemText}>{item.location}</Text>
</View>
<View style={{ flexDirection: 'row', marginTop: 5, padding: 10 }}>
<Image style={[styles.itemImage, { width: 15, height: 15, margin: 1 }]} source={require('./images/phone_icon.png')} />
<Text style={styles.itemText}>{item.phone}</Text>
</View>
</View>
</View>
);
}
renderSeparator() {
return <View style={styles.separator} />;
}
render() {
return (
<View style={styles.container} >
<Text style={styles.textStyle}>Transfer to Pharmacy</Text>
<View style={styles.childViewStyle}>
<FlatList
keyExtractor={this._keyExtractor}
data={this.state.data}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
textStyle: {
fontSize: 18,
color: Colors.black,
marginTop: 30,
marginLeft: 20
},
childViewStyle: {
margin: 20,
},
itemBlock: {
paddingVertical: 15,
},
itemImage: {
width: 50,
height: 50,
borderRadius: 25,
margin: 10
},
itemText: {
fontSize: 16,
justifyContent: 'center',
color: Colors.darkySkyBlue
},
itemName: {
fontSize: 20,
color: Colors.black,
},
separator: {
borderRadius: 4,
borderWidth: 1,
borderColor: Colors.lightGray,
},
pharmacyText: {
fontSize: 16,
fontFamily: Fonts.bold,
color: Colors.black
},
radioStyle: {
marginTop: 10,
marginRight: 50,
justifyContent: 'space-between'
},
arrowIconStyle: {
flexDirection: 'row',
justifyContent: 'space-between',
padding: 10
// flex: 1
}
});
with this code i am not able to select the radio button
Please let me know where it is going wrong as i am unable to select radio button in the flatlist separately.
i have changed onPress() like this
onPress( index) {
this.setState({ selected: index, });
}
and in renderItem method i have changed it like this
const { item, index } = data;
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selected === index}
onPress={() => this.onPress(index)}
/>
Now the output is like this
Now the first radio button is selected but when i tried to select other radio buttons they are not getting selected.
Here is my mock data file which is used for Flatlist.
export const PHARMACY = [
{
key: 0,
name: 'Plaza Pharmacy',
type: 'Urgent Care Center - 4.01 mi',
location: '3417 Gaston Avenue, Suite 195\n Dallas, TX 75202',
phone: '469.764.7100',
},
{
key: 1,
name: 'Courtyard Pharmacy',
type: 'Urgent Care Center - 4.09 mi',
location: '5236 West University Drive, Suite 1900\n MCKINNEY, TX 75071',
phone: '969.264.7190',
},
{
key: 2,
name: 'Outptaient Pharmacy at the Cancer Center',
type: 'Urgent Care Center - 4.66 mi',
location: '3800 Gaylord Parkway, Ste 110\n FRISCO, TX 75034',
phone: '890.664.8130',
},
{
key: 3,
name: 'Carrolton Pharmacy',
type: 'Urgent Care Center - 4.08 mi',
location: '5236 West University Drive, Suite 1900\n MCKINNEY, TX 75071',
phone: '969.264.7190',
},
{
key: 4,
name: 'Garland Pharmacy',
type: 'Urgent Care Center - 22.11 mi',
location: '3417 Gaston Avenue, Suite 195\n Dallas, TX 75202',
phone: '469.764.7100',
},
];
I am exporting this const PHARMACY and importing it in my class and set this to a state variable "data".
you can do something like this in renderItem
renderItem = ({item, index}) => {
.....
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selectedIndex === index}
onPress={() => {this.onPress(index)}}
/>
}
and replace onPress with
onPress = (index) => {
this.setState({ selectedIndex: index });
}
and update FlatList with extraData props as FlatList needs to be re-rendered as
<FlatList
keyExtractor={this._keyExtractor}
data={this.state.data}
renderItem={this.renderItem}
ItemSeparatorComponent={this.renderSeparator}
extraData={this.state}
/>
You can refer in snack here
First, you need to get the index of the current item like so:
const { item, index } = data;
After you get the index of the current item you can then check if the current radio button is selected or not and for changing the radio button you need to pass the value of the current index to the onPress function.
<RadioButton
innerColor={Colors.darkBlue}
outerColor={Colors.lightGray}
animation={'bounceIn'}
isSelected={this.state.selected === index}
onPress={() => this.onPress(index)}
/>

How to get the value selected using react-native-google-places-autocomplete ?

I am using react-native-google-places-autocomplete to select a location. I want to extract the location selected and use it as a props to be passed to another function. The value should be of type String. I do not how to extract the selected description value.
Here is what I have so far:
<GooglePlacesAutocomplete
placeholder='Event Location'
minLength={2} // minimum length of text to search
autoFocus={false}
// 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.warn(data, details);
props.location = data.description;
}}
textInputProps={{
onChangeText: (text) => { console.warn(text) }
}}
getDefaultValue={() => ''}
query={{
// available options: https://developers.google.com/places/web-service/autocomplete
key: 'AIzaSyCKwbZNUyUIx2X0XBBlWbhPu_unz5_1o3E',
language: 'en', // language of the results
types: 'geocode' // default: 'geocode'
}}
styles={{
textInputContainer: {
backgroundColor: 'rgba(0,0,0,0)',
borderTopWidth: 0,
borderBottomWidth:0,
},
description: {
fontWeight: 'bold',
},
textInput: {
marginLeft: 22,
marginRight: 0,
height: 38,
color: '#5d5d5d',
fontSize: 16,
},
predefinedPlacesDescription: {
color: '#1faadb'
}
}}
value={props.location}
onChangeText={props.onLocationChange}
renderLeftButton={() => <Text style={{ marginTop: 12, marginLeft:16, fontSize: 18 }}> Location </Text>}
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
debounce={200} // debounce the requests in ms. Set to 0 to remove debounce. By default 0ms.
/>
You will get the selected location in onPress callback of the component.
onPress={(data, details = null) => {
// 'details' is provided when fetchDetails = true
this.setState(
{
address: data.description, // selected address
coordinates: `${details.geometry.location.lat},${details.geometry.location.lng}` // selected coordinates
}
);
}}
This gives you the latitude and longitude:
onPress = {(data, details = null) => {
const { lat, lng } = details.geometry.location;
)}}