How to save an event in the local calendar using react-native.
The code of the whole app build here is available at https://github.com/Merlier/rn_example_calendar_events.git
Get started
Requirements:
- react-native >= 0.60
First just init a new react-native project:
$ npx react-native init rn_example_calendar_events
Install the react-native-calendar-events module:
$ npm install --save react-native-calendar-events
Write some functions to interact with local calendars
We will create some functions to interact with the local calendar using the react-native-calendar-events module.
Create a LocalCalendarService.js file with:
import RNCalendarEvents from 'react-native-calendar-events';
export const listCalendars = async () => {
let permissions;
let calendars = [];
try {
permissions = await RNCalendarEvents.checkPermissions();
if (permissions !== 'authorized') {
permissions = await RNCalendarEvents.requestPermissions();
}
if (permissions !== 'authorized') {
throw 'Access calendar not authorized';
}
calendars = await RNCalendarEvents.findCalendars();
} catch {}
return calendars;
};
export const addCalendarEvent = async (event, calendar) => {
let permissions;
let createdEvent = false;
try {
permissions = await RNCalendarEvents.checkPermissions();
if (permissions !== 'authorized') {
permissions = await RNCalendarEvents.requestPermissions();
}
if (permissions !== 'authorized') {
throw 'Access calendar not authorized';
}
const eventTmp = {...event};
eventTmp.calendarId = calendar.id;
createdEvent = await RNCalendarEvents.saveEvent(event.title, eventTmp);
} catch {}
return createdEvent;
};
Make a simple calendar list modal
Before saving an event in our local calendar, we need to choose in which calendar to save this event.
So let just build a simple component for it by creating the LocalCalendarModalComponent.js file with:
import React, {useState, useEffect} from 'react';
import {
StyleSheet,
Modal,
TouchableWithoutFeedback,
View,
ScrollView,
TouchableOpacity,
Text,
} from 'react-native';
import PropTypes from 'prop-types';
import {listCalendars} from './LocalCalendarService';
LocalCalendarModalComponent.propTypes = {
isVisible: PropTypes.bool,
closeModal: PropTypes.func,
handleCalendarSelected: PropTypes.func,
label: PropTypes.string,
modalTestID: PropTypes.string,
};
LocalCalendarModalComponent.defaultProps = {
isVisible: false,
closeModal: () => {},
handleCalendarSelected: () => {},
label: 'Select a calendar',
modalTestID: 'localCalendarModal',
};
function LocalCalendarModalComponent(props) {
const [calendars, setCalendars] = useState([]);
useEffect(() => {
const loadCalendars = async () => {
const calendarsTmp = await listCalendars();
setCalendars(calendarsTmp);
};
if (props.isVisible) {
loadCalendars();
}
}, [props.isVisible]);
return (
<Modal
transparent={true}
visible={props.isVisible}
onRequestClose={props.closeModal}
animationType="slide">
<TouchableWithoutFeedback
accessible={false}
onPress={props.closeModal}
style={styles.container}>
<View style={styles.backdrop}>
<View style={styles.agendaModalBody}>
<Text style={styles.title}>{props.label} :</Text>
<View style={styles.agendaList}>
<ScrollView>
{calendars.map((calendar, i) =>
calendar.allowsModifications ? (
<TouchableOpacity
key={i}
onPress={() => props.handleCalendarSelected(calendar)}
style={[
styles.calendarOption,
{backgroundColor: calendar.color},
]}>
<Text key={i} style={[styles.defaultText]}>
{calendar.title}
</Text>
</TouchableOpacity>
) : null,
)}
</ScrollView>
</View>
</View>
</View>
</TouchableWithoutFeedback>
</Modal>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
backdrop: {
flex: 1,
padding: '5%',
justifyContent: 'center',
backgroundColor: 'rgba(0,0,0,0.7)',
},
agendaModalBody: {
flexShrink: 1,
backgroundColor: '#fff',
padding: 5,
},
agendaList: {
marginTop: 10,
},
calendarOption: {
padding: 10,
},
});
export default LocalCalendarModalComponent;
Create an event
So now we are able to list our local calendars and save a new event in our selected calendar by our dedicated function.
Here we 've just have to create a form to save our event.
Modify your app.js like this:
/**
* Sample React Native App
* https://github.com/facebook/react-native
*
* @format
* @flow strict-local
*/
import React, {useState} from 'react';
import {
SafeAreaView,
StyleSheet,
View,
Text,
TextInput,
Button,
} from 'react-native';
import LocalCalendarModalComponent from './LocalCalendarModalComponent';
import {addCalendarEvent} from './LocalCalendarService';
const App: () => React$Node = () => {
const [isVisibleCalendars, setIsVisibleCalendars] = useState(false);
const [event, setEvent] = useState(null);
const [title, setTitle] = useState('');
const [startDateStr, setStartDateStr] = useState('');
const [endDateStr, setEndDateStr] = useState('');
const openLocalCalendarModal = () => setIsVisibleCalendars(true);
const closeLocalCalendarModal = () => setIsVisibleCalendars(false);
const saveEvent = async (calendar) => {
await addCalendarEvent(event, calendar);
closeLocalCalendarModal();
};
const saveEventCalendar = async () => {
const startDate = new Date(startDateStr);
const endDate = new Date(endDateStr);
const event = {
title: title,
startDate: startDate.toISOString(),
endDate: endDate.toISOString(),
allDay: true,
};
setEvent(event);
openLocalCalendarModal();
};
return (
<SafeAreaView style={styles.container}>
<LocalCalendarModalComponent
isVisible={isVisibleCalendars}
closeModal={closeLocalCalendarModal}
handleCalendarSelected={saveEvent}
label={'Select a calendar'}
/>
<View style={styles.form}>
<Text style={styles.title}>Save calendar event</Text>
<TextInput
style={styles.textInput}
placeholder={'Title'}
onChangeText={setTitle}
value={title}
/>
<TextInput
style={styles.textInput}
placeholder={'Start date YYYY-mm-dd'}
onChangeText={setStartDateStr}
value={startDateStr}
/>
<TextInput
style={styles.textInput}
placeholder={'End date YYYY-mm-dd'}
onChangeText={setEndDateStr}
value={endDateStr}
/>
<Button onPress={saveEventCalendar} title={'Save'} />
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#eee',
},
form: {
padding: 20,
},
title: {
fontSize: 20,
marginBottom: 20,
},
textInput: {
backgroundColor: '#fff',
marginBottom: 5,
},
});
export default App;
Now run the app:
$ npx react-native run-android
After you've created your new event with the app, don't forget to check the synchronization of your local calendar app.
More informations here: https://github.com/wmcmahan/react-native-calendar-events
Don't hesitate to refresh your local calendar several times before seeing your freshly created event.
Have fun
:)
Top comments (0)