Reputation: 127
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
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