Reputation: 37
I have used AJAX to request data from the database through an API. Here is the function.Since the formatting in the dB is different from the one Full Calendar requires, I have created an Object called schedule that looks the same as an Event Object to store each event item. Then push each object into an array called schedules. (In case anyone ask, reformattingTime() is just changing the string I get from database from HHMM to HH:MM:SS format)
function getCourse(arr){
$.ajax({
type: "GET",
url: '/course',
success: function(req){
for (var i = 0; i < req.length;i++){
var schedule = {daysOfWeek:[]};
schedule.title = req[i].course_name;
schedule.daysOfWeek = req[i].course_day;
schedule.startTime = reformattingTime(req[i].course_starttime);
schedule.endTime = reformattingTime(req[i].course_endtime);
arr.push(schedule);
}
},
error: function(err){
alert('Error:' + err);
}
}
)
}
here's how schedules[0] looks like
Next when I load the page, I add schedules as an event source then render the calendar. However, the events wouldn't appear in the calendar.
<script>
var schedules = [];
$(document).ready(function(){
getCourse(schedules);
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['timeGrid', 'dayGrid', 'interaction', 'list'],
header:{
left: 'timeGridWeek,listMonth'
},
defaultView: 'timeGridWeek',
});
calendar.addEventSource(schedules);
calendar.render();
});
If I hard code the array, the events can be displayed. I have checked that the schedule object from getCourse() is the same as the one I have hard coded.
<script>
var schedules = [{
title: "A1",
startTime: "18:00:00",
endTime: "20:00:00",
daysOfWeek:['1']
}];
$(document).ready(function(){
getCourse(schedules);
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['timeGrid', 'dayGrid', 'interaction', 'list'],
header:{
left: 'timeGridWeek,listMonth'
},
defaultView: 'timeGridWeek',
});
calendar.addEventSource(schedules);
calendar.render();
});
Upvotes: 2
Views: 59
Reputation: 1550
Your issue is that AJAX request is ASYNC. Which means rest of the code continue to execute before the request is complete. Which means your schedule is always be empty when calendar is instantiated. Therefore you need to wait until request is done. So you have to do something like below. I've also added some further code improvements you could make take advantage of ES6+ capabilities.
I don't know API call etc so can't really test it all but this is what you need to do.
function getCourse(arr) {
return $.ajax({ // return the promise
type: "GET",
url: '/course'
})
}
function renderCalendar(courseList) {
const calendarEl = document.getElementById('calendar');
const calendar = new FullCalendar.Calendar(calendarEl, {
plugins: ['timeGrid', 'dayGrid', 'interaction', 'list'],
header: {
left: 'timeGridWeek,listMonth'
},
defaultView: 'timeGridWeek',
});
calendar.addEventSource(schedules);
calendar.render();
}
function toCourseModel(course) {
return {
daysOfWeek: [],
title: req[i].course_name,
daysOfWeek: req[i].course_day,
startTime: reformattingTime(req[i].course_starttime),
endTime: reformattingTime(req[i].course_endtime),
}
}
// DOMContentLoaded
// @see https://developer.mozilla.org/en-US/docs/Web/Events/DOMContentLoaded
document.addEventListener('DOMContentLoaded', async (event) => { // ES6+ Native javascript.
console.log('DOM fully loaded and parsed');
const coursesList = await getCourse().catch(console.error) // await till async promise is complete
const transFormed = coursesList.map((course) => { // ES6 Array.map() method
return toCourseModel(course);
});
// Now create the calendar
renderCalendar(transFormed);
});
Upvotes: 1