Search code examples
c#jsonfullcalendarrazor-pagesfullcalendar-4

FullCalendar events not showing when from JSON feed


I have this FullCalendar portion of code on my page to pull events from an API controller in a Razor Pages project:

    var calendar;
        document.addEventListener('DOMContentLoaded', function () {
            var calendarEl = document.getElementById('calendar');
            calendar = new FullCalendar.Calendar(calendarEl, {
                plugins: ['dayGrid', 'interaction', 'list', 'timeGrid'],
                defaultView: 'dayGridMonth',
                customButtons: {
                    newEventButton: {
                        text: 'new event',
                        click: function () {
                            window.location.assign("Calendars/EditPersonnelEvent/0");
                        }
                    }
                },
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'newEventButton,dayGridMonth,timeGridWeek,timeGridDay'
                },
                events: "/api/fetchEvents"
            });
            calendar.render();
        })

and it seems to be working just fine, here's the snip of the fetch:

enter image description here

The problem is, the event fetched doesn't show on the calendar, on any of the views. When I paste that JSON into a hard-coded event, it works fine and I see the event, just not when it's from the GET. I've tried this with eventSources to no avail. I've searched about 30 different answers here and still no luck. The JSON seems to be formatted correctly, it seems to be getting fetched correctly, it's just not showing up. And yes, I'm looking at the correct days ;)

REQUESTED UPDATE:

Here is the "response" data:

enter image description here

and here's the .NET code for this fetch:

    [Route("api/fetchEvents")]
        [ApiController]
        public class FetchEventsController : ControllerBase
        {
            private readonly IPersonnelEventService _personnelEventService;

            public FetchEventsController(IPersonnelEventService personnelEventService)
            {
                _personnelEventService = personnelEventService;
            }

            // GET: api/FetchEvents/5
            [HttpGet]
            public string Get(string start, string end)
            {
                int currentUserId = User.Identity.GetUserId();
                DateTime objStart = DateTime.Parse(start, null, System.Globalization.DateTimeStyles.RoundtripKind);
                DateTime objEnd = DateTime.Parse(end, null, System.Globalization.DateTimeStyles.RoundtripKind);
                List<Entities.PersonnelEvent> events = new List<Entities.PersonnelEvent>(_personnelEventService.GetPersonnelEventsByUserId(currentUserId, objStart, objEnd));
                return JsonConvert.SerializeObject(events.Select(pe => pe.GetEventAsFullCalendarJson()).ToList());

            }
        }

and here's the code for "GetEventAsFullCalendarJson":

    public string GetEventAsFullCalendarJson()
            {
                var info = new
                {
                    title = Name,
                    start = StartDate,
                    end = EndDate
                };
                return JsonConvert.SerializeObject(info);
            }
        }

Solution

  • The problem is you are double-serializing your data.

    You serialise each event object individually in GetEventAsFullCalendarJson() when you do return JsonConvert.SerializeObject(info);. So at that point you already have a JSON string representing a single event.

    But then you combine all these together and serialise the whole thing again when you write return JsonConvert.SerializeObject(events.Select(pe => pe.GetEventAsFullCalendarJson()).ToList()); in the Get() method. This means the already-serialised JSON event strings are serialised again - which is why you've got quote marks round the event object (e.g. "{ ... }" and then escaped quotemarks (\") within it.

    The outcome is that to fullCalendar, your data just looks like an array of strings, not an array of event objects.

    The fix is simple - remove the serialisation of the individual events. An object/array must be serialised all at once to create a coherent single piece of JSON.

    This:

    return JsonConvert.SerializeObject(events.Select(pe => {
      title = pe.Name,
      start = pe.StartDate,
      end = pe.EndDate
    }).ToList());
    

    would work, I think.