Digital calendar users often need to create a series of events that repeat themselves without any additional settings. Businesses that have calendars built into their applications can improve the end-user experience by introducing a recurring events feature.
In this article, we explain the main aspects to consider when introducing recurring events in your application. We also share our experience implementing a recurring events feature in an app with the help of a practical example.
This article will be helpful for development teams and project leaders who are looking to improve the end-user experience of their applications with a built-in digital calendar.
Contents:
Recurring events in digital calendars
Many modern applications have built-in calendars, but not all of them allow for creating recurring events. A recurring event is an entry in a digital calendar that repeats itself. Usually, a user can choose any frequency for repeating the event: daily, weekly, monthly, annually, and so on.
When adding recurring event features to an app, there are some clear benefits for your end users, such as flexibility and improved time management. Users can easily modify their schedules without too much effort and without creating a new event every time they need one.
To create a recurring event in a calendar, you need to determine two parameters:
- Recurrence pattern is the frequency with which the event repeats itself. Common recurrence patterns are daily, weekly, relative/absolute monthly, or relative/absolute yearly.
- Recurrence range is the length of the pattern. Common options include a fixed number of repetitions, a specific end date, or no end date (recurring indefinitely).
Custom recurring events in calendars are a useful feature to incorporate into your app. Let’s see the key advantages of implementing a recurring events feature while you are developing a calendar application.
Build a feature-rich application that delights your users!
Get a solution tailored to your business needs by leveraging Apriorit’s SaaS and custom application development services.
Why should you add a recurring events feature to your app’s calendar?
Having an advanced calendar in your application might give you a competitive advantage and enhance the user experience. Here is what your end users will get after you add a recurring event feature to your application’s built-in calendar:
- Simple planning. With the help of a recurring events feature, users can easily schedule and repeat events without having to manually create the same meeting multiple times. This can save time, increase productivity, and provide scheduling clarity.
- Automation of repeated tasks. Recurring events can provide a better user experience by eliminating unnecessary clicks and steps required to schedule new meetings. You can also automate repetitive tasks, such as sending event reminders.
- Flexible planning. If a recurring events feature is implemented correctly, it provides more scheduling flexibility. End users can easily modify or cancel a meeting when needed.
Having an opportunity to seamlessly create repeated events is a useful feature for your application’s users. But how can you develop recurring events for calendar applications? Let’s take a look.
How to implement a recurring events feature
An end user can make a recurring event within a digital calendar in a straightforward fashion:
- Create the first entry in the calendar
- Add the same parameters that all repeated events in the series should contain
- Make changes later (if needed) to individual events or to the whole series of events
At the same time, a recurring events feature is not easy to deal with in applications from the point of view of developers. It involves tricky functionality, and many issues could arise during implementation, such as timezone management, edge cases, and possible performance issues. Before starting development, we recommend conducting a team meeting and discussing the next aspects to avoid some issues down the road:
- Format of recurring events. We recommend choosing the format that would be easiest to work with in the programming language of your application. In our case, this is the recurrence pattern used by Microsoft in Outlook.
- Generation of recurring events. Generating events is one of the most essential aspects in the development of recurring event functionality. You need to write code that generates recurring events based on the specified recurrence pattern.
- Creation of repeating events. After you have decided on the format of the recurring event, the next step is to think about the mechanism for its creation.
- Editing and deleting a recurring event. Now that you have determined the generation and creation flows for a series of meetings, you can also plan for ways to edit and delete instances of recurring events.
Say we have a project that requires adding recurring events during calendar app development. We will now take a closer look at how we can implement a recurring events feature with a practical example.
Read also
How to Build a SaaS Solution for Real Estate: Software Types, Key Features, and Development Nuances
Deliver efficient, scalable, and user-friendly SaaS solutions in the real estate sector. Read on to find valuable insights from Apriorit specialists.
Format of storing recurring events
The industry-standard Recurrence Rule (RRule) format is used by Google in Google Calendar. For our project, we chose the recurrence pattern used by Microsoft in Outlook because we were initially integrating our app with this software. Our application is developed in TypeScript, so it’s easy to work with.
Generation of recurring events
First and foremost, we don’t recommend storing the repeated meetings as separate instances in the database. This approach leads to database clogging, making data normalization impossible.
If an event in the user’s calendar needs to be repeated, it should be stored in the database as one single root record along with the recurrence pattern. All subsequent events will be generated in the runtime based on this pattern instead of being stored in the database as separate event instances.
To improve application performance, we have taken the following optimization measures:
- Used the memoization mechanism for a function that generates repeated events. This mechanism retrieves events from the cache instead of generating them from scratch.
- Added a caching mechanism based on Redux and RTK Query on the client side.
Your code has to include a specified recurrence pattern, which can involve looping through dates and checking if they match the recurrence pattern. You may also need to consider edge cases such as leap years and Daylight Savings Time.
Creation of recurring events
Depending on the chosen pattern format, you need to develop a mechanism for creating a pattern that will fit your project. As we mentioned in our example, we chose the pattern used by Microsoft in Outlook.
If you choose RRule as your format, you can look through the official documentation. There most likely is a library for generating/validating an RRule String for your programming language. For example, you can use this library for JS/TS.
The final aspect we want to discuss is enabling users to add or delete a recurring event. As this process is complex and has multiple scenarios, we discuss it in detail and with practical examples.
Editing and deleting a recurring event
Allowing end users to edit and delete a recurring event can be challenging, especially when you want to let them change only one event in a series. To implement different scenarios for event updates, you need to make changes to the chosen event and specify precisely what needs to be changed in a chosen event instance.
There are three possible options for editing and deleting recurring events:
- Modify all events — Edit or delete all events in the series
- Modify only the selected events — Edit or delete only selected events in the series
- Modify one event — Edit or delete only one event without disrupting the whole pattern.
In our project, we decided to implement all three options.
Here’s the body of the recurring occurrence update query we used for modifying recurring events:
{
"id": "Root meeting ID",
"startDate": "Meeting start ISO date",
"endDate": "Meeting end ISO date",
"updateType": "single" | "following" | "all"
}
This query is the basis of all the examples we discuss below.
Edit/delete all events in the series
When you need to edit or delete all events in the series, you can simply edit or delete the root instance in the database.
Here is what the query should look like:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"startDate": "2023-04-11T09:15:00Z",
"endDate": "2023-04-11T09:45:00Z",
"updateType": "all"
}
By adding this code to the original occurrence, you can edit or delete the whole series.
Edit/delete only the following events
Editing or deleting selected events is also not very complicated. You can split the original occurrence into two records, each with its own recurrence data.
The end date in the recurrence pattern of the original occurrence should be the end date that came from the client in your app minus one day. In this case, the new event is a complete copy of the original. But the start date for the recurrence pattern in the new event should be the start date that came from the client in your app.
Below, we provide practical examples made with the Microsoft Outlook recurrence format we used in one of our projects.
The original occurrence looks like this:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"title": "Test meeting",
"startDate": "2022-11-25T09:15:00Z",
"endDate": "2022-11-25T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "noEnd",
"endDate": "0001-01-01",
"startDate": "2022-11-22"
},
"pattern": {...}
}
}
Here is the query that came from the client:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"startDate": "2023-04-11T09:15:00Z",
"endDate": "2023-04-11T09:45:00Z",
"updateType": "following"
}
After performing all manipulations described above, the original occurrence will have the following code:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"title": "Test meeting",
"startDate": "2022-11-25T09:15:00Z",
"endDate": "2022-11-25T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "endDate", // Notice that type is changed also
"endDate": "2023-04-10" // 2023-04-11 minus 1 day,
"startDate": "2022-11-22"
},
"pattern": {...}
}
}
And this is the new occurrence:
{
"id": "5e76dd83-f499-4c13-89b6-5cc576a1028c",
"title": "Test meeting",
"startDate": "2023-04-11T09:15:00Z" // Time from the original meeting, date from the client query,
"endDate": "2023-04-11T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "noEnd",
"endDate": "0001-01-01",
"startDate": "2023-04-11" // Date from the client query
},
"pattern": {...}
}
}
Related project
Building a Microservices SaaS Solution for Property Management
Learn how the Apriorit team helped our client attract new customers and optimize maintenance costs by successfully replacing a monolithic architecture of their SaaS platform with microservices.
Edit/delete one event in a series
From our experience, this might be the trickiest scenario to handle. When editing or deleting an event in a series, you will have to make two copies of the root event instance.
The first copy is the non-recurring event that the user wants to edit. The second copy is a series that will continue after the event that the user wants to edit or delete.
We set the end of the root event pattern based on the formula that we used before, which is the end date that came from the client minus one day. Here is a known root occurrence instance, which is the initial occurrence of the recurring event:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"title": "Test meeting",
"startDate": "2022-11-25T09:15:00Z",
"endDate": "2022-11-25T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "noEnd",
"endDate": "0001-01-01",
"startDate": "2022-11-22"
},
"pattern": {...}
}
}
This is the query that came from the client:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"startDate": "2023-04-11T09:15:00Z",
"endDate": "2023-04-11T09:45:00Z",
"updateType": "single"
}
After the manipulations described above, you will have the following occurrence, which is the original occurrence minus one day:
{
"id": "0a54847a-c987-4815-8f71-1421e7eb289d",
"title": "Test meeting",
"startDate": "2022-11-25T09:15:00Z",
"endDate": "2022-11-25T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "endDate", // Notice that the type has also been changed
"endDate": "2023-04-10" // 2023-04-11 minus 1 day
"startDate": "2022-11-22"
},
"pattern": {...}
}
}
For the next series, we need to set the start of the recurrence pattern with the following formula: the start date that came from the client plus one day.
This is the occurrence that needs to be updated:
{
"id": "cb6a27cd-177f-4216-b6b0-015c992d45c9",
"title": "Test meeting",
"startDate": "2023-04-11T09:15:00Z",
"endDate": "2023-04-11T09:45:00Z",
"recurrencePattern": NUll // Recurrence pattern is NULL, so the event is non-recurring
}
This is the next series of occurrences that you will get in your calendar application:
{
"id": "dc6e1571-5a84-4f36-b5ff-99cb059e4a29",
"title": "Test meeting",
"startDate": "2023-04-12T09:15:00Z",
"endDate": "2023-04-12T09:45:00Z",
"recurrencePattern": {
"range": {
"type": "noEnd",
"endDate": "0001-01-01”,
"startDate": "2023-04-12" // 2023-04-11 plus 1 day
},
"pattern": {...}
}
}
Make sure to cover all your code in tests, as you are going to add a huge piece of code to your project.
Conclusion
There are many different ways of implementing a recurring events feature in the application development process. In this article, we explain what a recurring events feature is, why your digital calendar needs recurring events, and how you can implement this feature in your app. We also provide a practical example of creating, editing, and deleting recurring events.
Apriorit developers will gladly assist you with developing a calendar application and expanding its capabilities to meet your customers’ needs.
Need a reliable partner for your next application development project?
Get a dedicated team of experts and create scalable and user-friendly applications that will drive your business forward.