Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

blackshtef's avatar

Laravel 8 + FullCalendar 5 - Getting the events issue

I tried and went through dozens of blogposts and even some threads here on Laracasts, but no luck. I'm implementing a FullCalendar (with v5, I noticed it does matter since most blogposts I stumbled upon had some code that was depreciated) with a Laravel 8 project.

The issue I'm facing is that I can't get events to show up - I do get them in a JSON format out of the database, but I have trouble invoking that controller function - I'm basically sure it's just a semantic issue, but here it is.

So, this is my EventsController:

class EventsController extends Controller 
{
    public function index(Request $request)
    {
            $getEvents = Event::select('event_date', 'event_content')->get();
            $events = [];
                foreach ($getEvents as $values) {
                    $event = [];
                    $event['title'] = $values->event_content;
                    $event['start'] = $values->event_date;
                    $event['allDay'] = true;
                    $event['editable'] = false;
                    $events[] = $event;
                }
         		return response()->json($events);
    }

If I just return $events or return response()->json($events);-> I get this JSON (and that's ok, so, data is out of the DB):

[{"title":"John Doe - Hospital","start":"2022-08-18","allDay":true,"editable":false},{"title":"Mary Joe - Factory","start":"2022-08-19","allDay":true,"editable":false}]

This is my route:

Route::get('getEvents', 'App\Http\Controllers\EventsController@index')->name('getEvents');

and this is the script that initiates the calendar, placed inside the calendar.blade.php

            document.addEventListener('DOMContentLoaded', function() {
            var calendarEl = document.getElementById('calendar');
            var calendar = new FullCalendar.Calendar(calendarEl, {
                editable: false,
                droppable: true,
                selectable: true,
                initialView: 'dayGridWeek',
                views: {
                    dayGridWeek: {
                        type: 'dayGridWeek',
                        duration: { weeks: 2 },
                        buttonText: '4 day'
                    }
                },
                themeSystem: 'bootstrap5',
				editable: false,
                events: 'getEvents',
                displayEventTime: false,

But every time I get the error that Failure parsing JSON

Object { message: "Failure parsing JSON", xhr: XMLHttpRequest }
main.js:6262:21

​and when I look at the source code, there really aren't any events there. I think that the problem is somewhere in this events: 'getEvents' part - I would expect that 'getEvents' would somehow invoke the index function and get all the events, and that would work. If I hardcoded the JSON response into "events", everything works fine.

So, if anyone has any ideas on what to try out next - I would really appreciate it.

0 likes
18 replies
vybeauregard's avatar

Is the JSON response completely empty or does it have some invalid characters? Looking at that output will help determine the next step.

blackshtef's avatar

@vybeauregard THe JSON response is this:

[{"title":"John Doe - Hospital","start":"2022-08-18","allDay":true,"editable":false},{"title":"Mary Joe - Factory","start":"2022-08-19","allDay":true,"editable":false}]

The question actually is how to put it into the calendar JS

vybeauregard's avatar

@blackshtef What you have appears to be configured correctly. I'm wondering if calendar.blade.php is missing a calendar element, or perhaps multiple elements with an id of calendar?

blackshtef's avatar

@vybeauregard The calendar is displaying fine, I invoke it with within the calendar.blade.php. The script with the calendar settings is placed before the tag, and that part is within the app.blade.php layout file (which is included within the calendar.blade.php).

vybeauregard's avatar

@blackshtef Can you verify that the getEvents request is being called? It should appear in the network tab in your browser's devtools.

blackshtef's avatar

@vybeauregard I cannot :) When I look at the source code of the calendar, I see exactley this:

  themeSystem: 'bootstrap5',
				editable: false,
                **events: 'getEvents',**
                displayEventTime: false,

That's where the problem lies actually (I believe) - is "getEvents" the right thing to have here? Shouldn't it be something more "Laravel-y" :) I tried to have "events: {{route(getEvents)}} and when I look at the source code of that, I see that it has rendered to: events: https://test.local/getEvents So I'm thinking there must be something that I can do to actually execute that route and retrieve the array of events that is generated in the controller

Snapey's avatar

@vybeauregard Thats what I would suggest also. Check what request is being made by the calendar and what was the return payload. View the actual network request.

1 like
blackshtef's avatar

@Snapey https://imgur.com/a/LZOaTKX - This is what I get - but this is the result of the controller function (when I open up test.local/getEvents) - I don't believe this is from the calendar JS function; because, if that were the case, I would see the actual events (this response) in the "events" part of the calendar JS, no?

Snapey's avatar

Just looking at an implementation of Full Calendar I did maybe 6 years ago. The page has

	<script>
		$(document).ready(function(){
		    $('#calendar').fullCalendar({
			    events: '/ajax/volunteer/sample-event-for-demo-2/events',
			    aspectRatio: 2,
			    defaultDate: '2022-08-01',
			    timeFormat: 'h(:mm)a', // format accoriding to moment.js
			    // eventColor:' #55A79A',	
			    // displayEventTime:true,
			    eventClick: function(calEvent, jsEvent, view) {	
			    	location.assign('/' + calEvent.slug + '/event/' + calEvent.id);
			        console.log(calEvent);
			    },
			    eventRender: function(event, element) {
     				if(event.userIcon){          
				        element.find(".fc-title").append(" <i class='glyphicon glyphicon-user'></i>");
					}
				}  
		    });
		})
	</script>

You can see the events config element. This is the URL I see the calendar loading the events from

https://rotarota.net/ajax/volunteer/sample-event-for-demo-2/events?start=2022-07-31&end=2022-09-11&_=1660755971499

And in the Laravel end, I have to parse the start and end parameters to know which month the calendar is on so that the right events are returned.

[{"id":7721,"title":"Volunteer Day (0\/2)","start":"2022-08-24 00:00","filled":0,"total":2,"slug":"sample-event-for-demo-2","userIcon":false,"className":"empty"}]
blackshtef's avatar

@Snapey It motivated me to start from skratch, but somewhere mid-way I rearranged functions in the controller (check my answer I just posted) - that's where the actual problem was actually

blackshtef's avatar

So, managed to solve the problem 🥳 (and thank you all for the assistance!) This was the problem actually:

  1. the route was /getEvents and it was pointed to the index function of the controller. That function retrieved the data and packed it into an array with return $events;
  2. I didn't have a way to use that same function to "return $events" AND return the calendar.blade.php view. So basically, when user opens up test.local/getEvents, you would get only JSON data OR a rendered calendar with an error that JSON couldn't be parsed

So, within the EventsController I created a new function, calendar(), and edited the route to point to that function - so when a user opens up test.local/getEvents, it will call the calendar() function that will return the view, and within that view (calendar.blade.php) is a div with id="calendar" which will render the calendar, and calendar settings script has: events: 'getEvents' - and that works now like a charm :)

Just wanted to share my solution - if there is a more elegant solution, I would like to hear it :)

Cheers!

MichalOravec's avatar

@blackshtef Do you know collections?

class EventsController extends Controller
{
    public function index()
    {
        return Event::select('event_date', 'event_content')->get()->map(fn ($event) => [
            'title' => $event->event_content,
            'start' => $event->event_date,
            'allDay' => true,
            'editable' => false
        ]);
    }
}
blackshtef's avatar

@MichalOravec I used your example and it worked just fine! However, I would like to expand this a bit more - I'd like to add a different color to the events in the calendar based on a thing they applied to. So, I have two tables, events (that has, among other columns, activity_id with values 1, 2 or 3). Another table, activites, has activity_id and activity_color - red, white, green.

I would like, if a user applied to activity with ID 1 to be colored red, activity 2 white etc.

For that, I changed Event::select(...) to Event::all and addedd activity_id => $event->activity_id. But how would I pair that with activity_id and finally the color of the event, that would later be pushed to the calendar?

blackshtef's avatar

Let me answer to my own questions :) This is how I modified it:

return Event::select('activity_id')
->join('activities', 'events.activity_id', '=', 'activities.activity_id')
->select('activities.activity_color', 'event_content', 'event_date')
->get()->map(fn ($events) => [...
Snapey's avatar

typically you would have the route for the user and an 'api' or 'ajax' route for the component data. It seems a bit backward that the index route goes to the calendar function and the getEvents route goes to the index function?

blackshtef's avatar

@Snapey Yes, that makes sense. I will definitely rename the functions, and I'll try to use what you proposed here - an api or ajax route for retriveing the data.

Please or to participate in this conversation.