DEV Community

Merlier
Merlier

Posted on

Create an event in local calendar using react-native

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
Enter fullscreen mode Exit fullscreen mode

Install the react-native-calendar-events module:

$ npm install --save react-native-calendar-events
Enter fullscreen mode Exit fullscreen mode

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;
};

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

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;

Enter fullscreen mode Exit fullscreen mode

Now run the app:

$ npx react-native run-android
Enter fullscreen mode Exit fullscreen mode

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.

Alt Text

Have fun
:)

Top comments (0)