← All articles

Mapping data into FullCalendar events

Mapping a record into a calendar event is only the presentation step, not an implemented reservation system.

t.Turgay
Mapping data into FullCalendar events

Displaying a meal as a calendar event is straightforward. Safely reserving its final place is a different feature. The single-file reservation UI in my archive is useful for separating FullCalendar's presentation model from an authoritative reservation service; the UI file alone does not demonstrate persisted bookings.

Map business data into the event contract

The sample meal has ID one, capacity twenty and seven reservations, leaving thirteen. Its 2026-10-17 value represents a calendar day, so allDay is true. The pure toEvent mapping can run under Node.js; the commented calendar setup requires the browser library.

export function toEvent(meal){
  if(!/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/.test(meal.date))throw new Error('Expected ISO date');
  return {id:String(meal.id),title:meal.name,start:meal.date,allDay:true,
    extendedProps:{remaining:meal.capacity-meal.reserved}};
}
console.log(JSON.stringify(toEvent({id:1,name:'Lunch',date:'2026-10-17',capacity:20,reserved:7})));
// Browser integration:
// new FullCalendar.Calendar(element, {
//   events: meals.map(toEvent),
//   eventClick: info => { details.textContent = info.event.title; }
// });

A string ID supports stable event identity, title supplies the label and start supplies the date. Application data such as remaining belongs in extendedProps rather than being mixed indiscriminately with the calendar's own event fields.

A date-shaped string is not necessarily a valid date

The regex checks only the yyyy-MM-dd shape. It accepts 2026-02-31 even though that is not a calendar date. Validate actual calendar values at the input boundary instead of relying on Date normalization to roll invalid days into another month. Date-only values and instants also require different contracts.

Converting an all-day date through UTC unnecessarily can shift the displayed day. Timed events instead need an explicit offset and calendar time-zone policy. The same string shape should not silently carry different meanings across endpoints.

Understand the end boundary

FullCalendar's exclusive end is a common source of mistakes in multi-day events. The last visible day and the end value are not interchangeable. This sample has no end field and represents one day; a later range extension needs tests covering start, end and visible dates together.

Displayed capacity is not a reservation lock

The client can calculate capacity minus reserved, but two users can both see one remaining place. The server accepting reservations must protect that decision atomically. A submitted remaining count or disabled button is not authoritative. Authorization, date availability and duplicate-booking rules belong in the same business flow.

Cancelled, closed and full events may need explicit state. Clamping negative remaining values to zero can conceal inconsistent data. Coloring an event red does not repair its underlying capacity rule.

Keep clicking and data loading within their boundaries

The example uses textContent for the clicked title rather than injecting user text as HTML. A real detail view can request authorized data by event ID. Fields already visible in the calendar should not become permission claims.

Large calendars can load only the visible range. Rapid month navigation needs stale-response protection, and stable event IDs make later refreshes easier to reconcile. Test valid days, date-shaped invalid input, full capacity, concurrent reservations and multi-day end boundaries. Most mapping checks can run before the calendar component is rendered.

FullCalendar event contract; Time-zone behavior.

✳ You have reached the end of this orbit.
Explore more articles →
turgay.A little code, a few pixels, a lot of curiosity.© 2026 · Made on Earth ✳