"Uncaught TypeError: Cannot read property 'clone' of undefined" when adding recurring events to database

11.2k Views Asked by At

For some reason I'm getting ""Uncaught TypeError: Cannot read property 'clone' of undefined" when I'm trying to update the calendar with a recent set of recurring event using $('#calendar').fullCalendar('updateEvent',events[i]); in the sucess call of my ajax (check last code snippet)

This is the structure of my function call:

I'm calling addEventSource inside the eventReceive function so when an element is dragged to the calender, this is deleted and the recurring events are added:

eventReceive : function(event) {
    ...
     $('#calendar').fullCalendar('removeEvents', event._id);
    $('#calendar').fullCalendar(  'addEventSource',function(start, end, status,  callback) {    

Inside addEventSource, i simply check the day of the week that the event has been dropped upon and duplicate that for upcoming days of the same day:

$('#calendar').fullCalendar( 'addEventSource',function(start, end, status,  callback) {
  var start_date = event.start.toDate();
  var stop_date = new Date("2017-01-15"); // for testing purposes to avoid filling up database with too many entries
  var events = [];
  ...
    for (loop = start_date.getTime(); (loop <= end._d.getTime()) && (loop <= stop_date); loop = loop + (24 * 60 * 60 * 1000)) { 
       ...
       var test_date = new Date(loop);
       var momentOfDate = moment(test_date);
       var formattedStart = momentOfDate.format("YYYY-MM-DDTHH:mm:ss");
       ...
        if (test_date.getDay() == event.start.weekday()) {
              events.push({
                                title: event.title,
                                start: formattedStart,
                                end: // same procedure for end as start
                                parent_id : // some variable
                                id: // some unique variable,
                                tDuration : event.tDuration,
                                dow : ''
          });
        } //if          
     } // for loop
     callback(events);

After the callback, we would like to add the newly created events to the database. And this works just fine, every recurring event i added is in the database IF i exclude the "$('#calendar').fullCalendar('updateEvent',events[i]);" function call but then I need to reload the page in order for the database to update when i move events around. This is the ajax call:

for (i = 0 ; i < events.length-1 ; i++) {
        var duration = events[i].tDuration;
        $.ajax({
            url: 'process.php',
            data: 'type=new&title='+events[i].title+'&startdate='+events[i].start+'&duration='+duration+'&enddate='+events[i].end+'&dow='+events[i].dow,
            type: 'POST',
            dataType: 'json',
            success: function(response){
                //location.reload(); WORKS but requires reload
                  $('#calendar').fullCalendar('updateEvent',events[i]); // generates typeError but needed in order modify recurring events

                            },
            error: function(e){
                    alert('error');
                    console.log(e.responseText);
                }
            })
        }

What do i do in this situation? I can without problems add a single event and perform an identical version of the ajax without any errors, the problem occurs when I try and access the events in my own 'events' array instead of using the event passed as an argument in the eventReceive function call. However since I'm adding multiple events I'm kinda forced to do it the way that I'm doing it it seems like.

Code for solo event (WORKS!):

 eventReceive : function(event) {
            var title = event.title;
            var start = event.start.format();
            var end = event.end.format();
            var duration = event.tDuration;
            var dow ='';
            $.ajax({
                url: 'process.php',
                data: 'type=new&title='+title+'&startdate='+start+'&duration='+duration+'&enddate='+end+'&dow='+dow,
                type: 'POST',
                dataType: 'json',
                success: function(response){
                    event.id = response.eventid;
                    $('#calendar').fullCalendar('updateEvent',event);
                },
                error: function(e){
                    alert('error');
                    console.log(e.responseText);
                }
            });

removed attempt1 cus found a solution myself that worked

2

There are 2 best solutions below

8
On BEST ANSWER

When you call updateEvent, event must be the original Event Object for an event, not merely a reconstructed object.

So you will either have to get the original event and update the properties on it and then call updateEvent or you could call removeEvents passing the id and then call renderEvent passing the event from your array.

1
On

So i've been struggling with this for some time now and finally found the best solution. For recurring events dont use the addEventSource function, it creates too much chaos with the callback function. Just create a for loop, define a new varr for event and add properties, use $('#calendar').fullCalendar('renderEvent',event,true) to add the event to calendar so it sticks and then use ajax() call to add the event to the database so when you refresh it stays.

id_mix = 0;
// TRAVERSE THROUGH TIME
for (loop = start_date.getTime(); (loop <= stop_date); loop = loop + (24 * 60 * 60 * 1000))
...
if (test_date.getDay() == event.start.day()) { // LOOK FOR DAY TO RECUR ON
    var myEvent = { // CREATE EVENT
           title: event.title,
           start: // formatted start date 
           id : id_mix
    }
    id_mix++;
    $.ajax({
         url: 'process.php',
         data: 'type=newR&title='+myEvent.title,
         type: 'POST',
         dataType: 'json',
         async: false,
        success: function(response){
            new_id = response.eventid;
                                },
        error: function(e){
            alert('error');
            console.log(e.responseText);
            }
        });
    myEvent.id = new_id; // GET ID FROM DATABASE, USE ASYNC = FALSE TO RETREIVE VALUE
    $('#calendar').fullCalendar('renderEvent',myEvent,true) // STICK TRUE IN CASE YOU SWAP VIEW


 ...