Hello,
I am trying to retrieve contacts from Andriod using Expo Contacts API.
But facing the below error
Can someone help look into this please
[11:28:15] [Unhandled promise rejection: TypeError: undefined is not an object (evaluating ‘_expo.default.Permissions’)]
*** screens/AddEventScreen.js:46:34 in componentDidMount$**
- node_modules/regenerator-runtime/runtime.js:62:44 in tryCatch
import React from 'react';
import { Alert, StyleSheet, Text, View, ScrollView, Platform } from 'react-native';
import {
Button,
Container,
Content,
DatePicker,
Form,
Icon,
Item,
Input,
Label,
Picker,
Textarea
} from 'native-base';
import AutoTags from 'react-native-tag-autocomplete';
import Expo from 'expo';
export default class AddEventScreen extends React.Component {
static navigationOptions = {
title: 'New Event',
};
constructor(props) {
super(props);
this.state = {
chosenDate: new Date() ,
selected: "00",
fromHour: "00",
fromMin: "00",
toHour: "00",
toMin: "00",
contacts: [], // Will be populated during component mount
suggestions : [{name:'Mickey Mouse'}, {'name': 'Bakthavatchalam'}],
tagsSelected : [],
};
this.setDate = this.setDate.bind(this);
this.handleDelete = this.handleDelete.bind(this);
this.handleAddition = this.handleAddition.bind(this);
this.componentDidMount = this.componentDidMount.bind(this);
}
async componentDidMount() {
const time = Date.now();
const permission = await Expo.Permissions.askAsync(Expo.Permissions.CONTACTS);
if (permission.status !== 'granted') { return; }
const contacts = await Expo.Contacts.getContactsAsync({
fields: [
Expo.Contacts.PHONE_NUMBERS,
Expo.Contacts.EMAILS,
Expo.Contacts.FIRST_NAME,
Expo.Contacts.LAST_NAME
],
pageSize: 10000,
pageOffset: 0,
}).then(({data, hasNextPage, hasPreviousPage, total}) => {
var contactDetails = [];
for (var i=0; i<data.length; i++){
contactDetails.push({
name: data[i].givenName + ' ' + data[i].familyName,
phoneNumbers: data[i].phoneNumbers
});
}
this.setState({contacts: contactDetails});
});
}
handleDelete(index) {
let tagsSelected = this.state.tagsSelected;
tagsSelected.splice(index, 1);
this.setState({ tagsSelected });
}
handleAddition(suggestion) {
presentNames = [];
for(var i =0;i<this.state.tagsSelected.length;i++){
presentNames.push(this.state.tagsSelected[i].name);
}
if (presentNames.indexOf(suggestion.name) == -1){
this.setState({ tagsSelected: this.state.tagsSelected.concat([suggestion])});
}
}
setDate(newDate) {
this.setState({ chosenDate: newDate });
}
onFromHourValueChange(value: string) {
this.setState({
fromHour: value
});
}
onFromMinValueChange(value: string) {
this.setState({
fromMin: value
});
}
onToHourValueChange(value: string) {
this.setState({
toHour: value
});
}
onToMinValueChange(value: string) {
this.setState({
toMin: value
});
}
handleChange(selectedOption: object) {
this.setState({ selectedOption });
}
render(){
return (
<ScrollView style={styles.container} contentContainerStyle={styles.contentContainer}>
<View style={{flex: 1, flexDirection: 'column'}}>
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'flex-end', alignContent: 'flex-end'}}>
<Button iconLeft transparent primary>
<Icon name='md-save'/>
</Button>
<Button iconLeft transparent primary>
<Icon name='md-close'/>
</Button>
</View>
<View style={{marginLeft: 15}}>
<AutoTags
suggestions={this.state.contacts}
tagsSelected={this.state.tagsSelected}
handleAddition={this.handleAddition}
handleDelete={this.handleDelete}
placeholder="Add a contact.." />
</View>
<Container>
<Form>
<Item floatingLabel>
<Label>Subject</Label>
<Input/>
</Item>
<Item floatingLabel>
<Label>Description</Label>
<Textarea rowSpan={5}/>
</Item>
<Item floatingLabel>
<Label>Location</Label>
<Input/>
</Item>
<Item>
<Label>Date</Label>
<DatePicker
defaultDate={new Date(2018, 4, 4)}
minimumDate={new Date(2018, 1, 1)}
maximumDate={new Date(2018, 12, 31)}
locale={"en"}
timeZoneOffsetInMinutes={undefined}
modalTransparent={false}
animationType={"fade"}
androidMode={"default"}
placeHolderText="Select date"
textStyle={{ color: "green" }}
placeHolderTextStyle={{ color: "#d3d3d3" }}
onDateChange={this.setDate}
disabled={false}/>
</Item>
<Item>
<Label>From</Label>
<View style={{flex: 1, flexDirection: 'row'}}>
<Picker
mode="dropdown"
placeholder="Hour"
iosIcon={<Icon name="arrow-down" />}
headerBackButtonText="Baaack!"
selectedValue={this.state.fromHour}
onValueChange={this.onFromHourValueChange.bind(this)}
>
<Picker.Item label="00" value="00" />
<Picker.Item label="01" value="01" />
<Picker.Item label="02" value="02" />
<Picker.Item label="03" value="03" />
<Picker.Item label="04" value="04" />
<Picker.Item label="05" value="05" />
<Picker.Item label="06" value="06" />
<Picker.Item label="07" value="07" />
<Picker.Item label="08" value="08" />
<Picker.Item label="09" value="09" />
<Picker.Item label="10" value="10" />
<Picker.Item label="11" value="11" />
<Picker.Item label="12" value="12" />
<Picker.Item label="13" value="13" />
<Picker.Item label="14" value="14" />
<Picker.Item label="15" value="15" />
<Picker.Item label="16" value="16" />
<Picker.Item label="17" value="17" />
<Picker.Item label="18" value="18" />
<Picker.Item label="19" value="19" />
<Picker.Item label="20" value="20" />
<Picker.Item label="21" value="21" />
<Picker.Item label="22" value="22" />
<Picker.Item label="23" value="23" />
</Picker>
<Picker
mode="dropdown"
placeholder="Minutes"
iosIcon={<Icon name="arrow-down" />}
headerBackButtonText="Baaack!"
selectedValue={this.state.fromMin}
onValueChange={this.onFromMinValueChange.bind(this)}
>
<Picker.Item label="00" value="00" />
<Picker.Item label="15" value="15" />
<Picker.Item label="30" value="30" />
<Picker.Item label="45" value="45" />
</Picker>
</View>
</Item>
<Item>
<Label>To</Label>
<View style={{flex: 1, flexDirection: 'row'}}>
<Picker
mode="dropdown"
placeholder="Hour"
iosIcon={<Icon name="arrow-down" />}
headerBackButtonText="Baaack!"
selectedValue={this.state.toHour}
onValueChange={this.onToHourValueChange.bind(this)}
>
<Picker.Item label="00" value="00" />
<Picker.Item label="01" value="01" />
<Picker.Item label="02" value="02" />
<Picker.Item label="03" value="03" />
<Picker.Item label="04" value="04" />
<Picker.Item label="05" value="05" />
<Picker.Item label="06" value="06" />
<Picker.Item label="07" value="07" />
<Picker.Item label="08" value="08" />
<Picker.Item label="09" value="09" />
<Picker.Item label="10" value="10" />
<Picker.Item label="11" value="11" />
<Picker.Item label="12" value="12" />
<Picker.Item label="13" value="13" />
<Picker.Item label="14" value="14" />
<Picker.Item label="15" value="15" />
<Picker.Item label="16" value="16" />
<Picker.Item label="17" value="17" />
<Picker.Item label="18" value="18" />
<Picker.Item label="19" value="19" />
<Picker.Item label="20" value="20" />
<Picker.Item label="21" value="21" />
<Picker.Item label="22" value="22" />
<Picker.Item label="23" value="23" />
</Picker>
<Picker
mode="dropdown"
placeholder="Minutes"
iosIcon={<Icon name="arrow-down" />}
headerBackButtonText="Baaack!"
selectedValue={this.state.toMin}
onValueChange={this.onToMinValueChange.bind(this)}
>
<Picker.Item label="00" value="00" />
<Picker.Item label="15" value="15" />
<Picker.Item label="30" value="30" />
<Picker.Item label="45" value="45" />
</Picker>
</View>
</Item>
</Form>
</Container>
</View>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
button: {
height: 30,
width: 100,
justifyContent: 'center'
},
container: {
flex: 1,
backgroundColor: '#fff',
fontSize: 10,
marginLeft: 10,
marginTop: 3
},
contentContainer: {
paddingTop: 3
},
});