MVM
MVM

Reputation: 127

FullCalendar initializing before events load

I have a FullCalendar that takes in an array(selectedEvents) from a function that uses the Location ID that is pulled from the url. The array is built onInit as is the calendar but the calendar has a timeout on it in order to allow the events to populate. When the calendar is initially navigated to from another part of the website, the events for the Default Location are not displayed but they are populated into the selectedEvents array. When I click on another location's calendar, the events are populated and then displayed correctly. The calendar works correctly thereforth. I believe the calendar is taking precedence over the population of events during the first initialization of the calendar even though it is wrapped in a timeout. I've seen this question once before on SO but it was not answered.

I've already tried extending the timeout of the calendar

   getLocationEvents(location: PFLocation) {
    // if (this.allEvents) {
    this.selectedEvents = [];
    if (location.events) {
        console.log(location.events);
        this.eventIdArray = location.events;
        for (let event of this.eventIdArray) {
            this.eventService.get(event).subscribe(data => {
                console.log(data);
                this.selectedEvents.push(data);
            });
        }
    } else {
        return;
    }
    console.log(this.selectedEvents);
    return this.selectedEvents;
}

getBatchEvents(location: PFLocation) {
    var that = this;
    if (this.allEvents) {
        if (location.batches) {
            let batches = location.batches;
            for (let batch of batches) {
                this.batchService.get(batch).subscribe(data => {
                    for (let event of data.events) {
                        this.eventService
                            .get(event)
                            .subscribe(eventData => {
                                console.log(eventData);

                              this.selectedEvents.push(eventData);
                            });
                    }
                });
            }
            console.log(this.selectedEvents);
            console.log('out of Batch Events');
            return this.selectedEvents;
        }
    }
    if (!this.allEvents) {
        this.selectedEvents = [];
        if (location.batches) {
            let batches = location.batches;
            for (let batch of batches) {
                this.batchService.get(batch).subscribe(data => {
                    for (let event of data.events) {
                        this.eventService
                            .get(event)
                            .subscribe(eventData => {
                                console.log(eventData);

                           this.selectedEvents.push(eventData);
                            });
                    }
                });
            }
            console.log(this.batchEvents);
            console.log('out of Batch Events');
            return this.selectedEvents;
        }
    }
}

getAllEvents(location: PFLocation) {
    this.allEvents = true;
    var that = this;
    that.getLocationEvents(location);
    that.getBatchEvents(location);
}

ngOnInit() {
    let that = this;
    this.sub = this.route.params.subscribe(params => {
        this.locationId = params['locationid'];
        this.userService
            .getLocation(this.locationId)
            .subscribe(location => {
                console.log('Out of on Init');
                this.selectedLocation = JSON.parse(
                    JSON.stringify(location)
                );
                that.getAllEvents(this.selectedLocation);
                console.log(this.selectedLocation);
            });`enter code here`
        console.log(this.selectedLocation);
        if (this.locationId) {
            const today = new Date();
            const y = today.getFullYear();
            const m = today.getMonth();
            const d = today.getDate();
            $('#fullCalendar').fullCalendar('removeEvents');
            $('#fullCalendar').fullCalendar(
                'addEventSource',
                that.selectedEvents
                );
            setTimeout(function() {
                $('#fullCalendar').fullCalendar({
                    viewRender: function(view: any, element: any){
                        // We make sure that we activate the 
                   perfect scrollbar when the view isn't on Month
                        if (view.name != 'month') {
                            var elem = $(element).find('.fc- 
                             scroller')[0];
                            let ps = new PerfectScrollbar(elem);
                        }
                    },
                    header: {
                        left: 'title',
                        center: 'month, agendaWeek, agendaDay',
                        right: 'prev, next, today'
                    },
                    defaultDate: today,
                    selectable: true,
                    selectHelper: true,
                    views: {
                        month: {
                            // name of view
                            titleFormat: 'MMMM YYYY'
                            // other view-specific options here
                        },
                        week: {
                            titleFormat: ' MMMM D YYYY'
                        },
                        day: {
                            titleFormat: 'D MMM, YYYY'
                        }
                    },
                    eventLimit: true, // allow "more" link when 
                     too many events
                    select: function(start: any, end: any) {
                        that.openEventForm();
                    },
                    eventClick: function(event, jsEvent) {
                        that.completeEventForm(event);
                    }
                });
            }, 500);
        }
    });
}

I expect the calendar to be populated the first time I navigate to the page.

Upvotes: 1

Views: 970

Answers (1)

MVM
MVM

Reputation: 127

Aside from refactoring the backend and eliminating the spaghetti code it wasn't a difficult issue once someone pointed out how the calendar inits. First the calendar has to grab onto the DOM element then it grabs the event source. If it doesn't grab the #calendar then it won't grab the event source until the next time it's initialized and at that point it is using the old event source data(if set up as my code was). "viewRender" needs to happen first, then "removeEvents" then "addEventSource".

getLocationEvents(location: PFLocation) {
        if (location.events) {
            return this.eventService
                .getFaciltyTasks(location._id)
                .subscribe(data => {
                    console.log(data);
                    this.facilityEvents = data;
                });
        }
    }

    getAllBatchEvents(location: PFLocation) {
        return this.eventService
            .getAllCultivationTasks(location._id)
            .subscribe(data => {
                console.log(data);
                this.cultivationEvents = data;
            });
    }

    getBatchEvents(batchId: string) {
        return this.eventService.getBatchTasks(batchId).subscribe(data => {
            console.log(data);
            this.batchEvents = data;
        });
    }

    editEventForm() {
        this.state = 'editEvent';
    }

    getAllEvents(location: PFLocation) {
        var that = this;
        return new Promise(resolve => {
            return this.eventService
            .getAllLocationTasks(location._id)
            .subscribe(data => {
                console.log(data);
                that.selectedEvents = data;
                that.calInit();
                resolve(that.selectedEvents);
            });
        });
    }

    calInit() {
        var that = this;
        const $calendar = $('#fullCalendar');
        console.log(that.locationId);
        if (this.selectedEvents) {
            const today = new Date();
            const y = today.getFullYear();
            const m = today.getMonth();
            const d = today.getDate();
            $calendar.fullCalendar({
                viewRender: function(view: any, element: any) {
                    // We make sure that we activate the perfect scrollbar when the view isn't on Month
                    if (view.name != 'month') {
                        var elem = $(element).find('.fc-scroller')[0];
                        let ps = new PerfectScrollbar(elem);
                    }
                },
                customButtons: {
                    filter: {
                        text: 'filter',
                        click: function() {
                            that.open();
                        }
                    }
                },

                // events: that.selectedEvents,
                header: {
                    left: 'title',
                    center: 'filter, month, agendaWeek, agendaDay',
                    right: 'prev, next, today'
                },
                defaultDate: today,
                selectable: true,
                selectHelper: true,
                views: {
                    month: {
                        // name of view
                        titleFormat: 'MMMM YYYY'
                        // other view-specific options here
                    },
                    week: {
                        titleFormat: ' MMMM D YYYY'
                    },
                    day: {
                        titleFormat: 'D MMM, YYYY'
                    }
                },
                eventLimit: true, // allow "more" link when too many events
                select: function(start: any, end: any) {
                    that.openEventForm();
                },
                eventClick: function(event, jsEvent) {
                    that.eventLocation = new PFLocation({});
                    that.eventBatch = new Batch();
                    that.eventRoom = new Room();
                    that.viewEvent(event);
                }
            });
            $calendar.fullCalendar('removeEvents');
            $calendar.fullCalendar('addEventSource', that.selectedEvents);
        }
    }

    ngOnInit() {
        // const $calendar = $('#fullCalendar');
        let that = this;
        // that.filter = false;
        this.sub = this.route.params.subscribe(params => {
            that.locationId = params['locationid'];
            if (that.locationId) {
                that.AuthService.getCurrentUser().then(user => {
                    that.currentUser = user;
                    var locations = that.currentUser.locations.admin.concat(
                        that.currentUser.locations.user
                    );
                    var location = find(locations, function(location) {
                        return location._id == that.locationId;
                    });
                    console.log(location);
                    console.log(that.currentUser);
                });
            }

            this.userService
                .getLocation(this.locationId)
                .subscribe(location => {
                    console.log('Out of on Init');
                    this.selectedLocation = JSON.parse(
                        JSON.stringify(location)
                    );
                    that.getAllEvents(this.selectedLocation);
                    console.log(this.selectedLocation);
                });
            console.log(this.selectedLocation);
        });
    }

Upvotes: 1

Related Questions