Summary: The idea of the below example is to simulate a case where we render a SchedulerPro instance without data while the data is being pulled async. Once the data is being pulled it is loaded & another request that pulls updated data is being simulated. After the updated data is pulled we want to merge it with the existing data instead of replacing it that is where syncDataOnLoad comes into play. The problem is that after the loaded is updated visually the rendered events do not changes at the same time event tooltips show the updated values.
If i call manually the method( in my case 'await updateData();' from the browser console ) that loads the updated data events are visually updated.
If i remove 'repopulateOnDataset : false' i get 'Uncaught (in promise) Error: Already entered replica'
Removing both 'syncDataOnLoad: true' & 'repopulateOnDataset : false' works as expected
Static example:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<script type="text/javascript" src="./schedulerpro-4.0.8/build/schedulerpro.umd.js"></script>
<link rel="stylesheet" href="./schedulerpro-4.0.8/build/schedulerpro.material.css" id="bryntum-theme" />
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
</head>
<body id="rootContainer">
<script type="text/javascript">
const resources = [
{
"id":"userID1"
,"name":"Test User"
}
]
, events = [
{
"id": "eventRecord1",
"name": "Task #1",
"startDate": new Date( 2021, 2, 3, 9, 0, 0 ),
"endDate": new Date( 2021, 2, 5, 18, 0, 0 )
}, {
"id": "eventRecord2",
"name": "Task #2",
"startDate": new Date( 2021, 2, 3, 9, 0, 0 ),
"endDate": new Date( 2021, 2, 5, 18, 0, 0 )
}
]
, assignments = [
{
"id": 2,
"eventId": "eventRecord1",
"resourceId": "userID1",
"event": "eventRecord1",
"resource": "userID1"
}, {
"id": 3,
"eventId": "eventRecord2",
"resourceId": "userID1",
"event": "eventRecord2",
"resource": "userID1"
}
];
const scheduler = new bryntum.schedulerpro.SchedulerPro({
appendTo : 'rootContainer'
, project: {
eventStore: new bryntum.schedulerpro.EventStore({
data: []
, syncDataOnLoad: true
})
, repopulateOnDataset : false
, resourceStore: new bryntum.schedulerpro.ResourceStore({
data: []
})
, assignmentStore: new bryntum.schedulerpro.AssignmentStore({
data: []
})
, calendarManagerStore: new bryntum.schedulerpro.CalendarManagerStore({
data: [{
id: "workhours"
, name: "Working hours"
, unspecifiedTimeIsWorking: false
, intervals: [
{
recurrentStartDate: "at 9:00"
, recurrentEndDate: "at 13:00"
, isWorking: true
},{
recurrentStartDate: "at 14:00"
, recurrentEndDate: "at 18:00"
, isWorking: true
}
]
}]
})
, calendar: "workhours"
}
, columns : [
{ text: 'Employee', field: 'name' }
, { text: 'Email', field: 'email' }
]
, readOnly: true
, features : {
taskEdit : false
}
//set calendar columns visualisation
, viewPreset: {
base: 'hourAndDay'
, tickWidth: 30
, displayDateFormat: 'll HH:mm'
, headers: [
{
unit: 'day'
, dateFormat: 'ddd DD/MM' //Mon 01/10
},{
unit: 'hour'
, dateFormat: 'HH'
}
]
}
});
function loadData(){
console.log( "load data start" );
return scheduler.resourceStore.loadDataAsync( resources )
.then( () => {
return scheduler.assignmentStore.loadDataAsync( assignments );
})
.then( () => {
let loadDataPromise = scheduler.eventStore.loadDataAsync( events );
loadDataPromise.then( _onEventStoreLoad );
return loadDataPromise;
});
}
const _onEventStoreLoad = function(){
let eventStore = scheduler.eventStore
, startDate = null
, endDate = null;
for( let index = 0, count = eventStore.getCount(); index < count; index++ ){
let eventObj = eventStore.getAt( index );
if( startDate === null || startDate > eventObj.startDate ){
startDate = eventObj.startDate;
}
if( endDate === null || endDate < eventObj.endDate ){
endDate = eventObj.endDate;
}
}
if( startDate && endDate === null ){
endDate = startDate;
}
else if( endDate && startDate === null ){
startDate = endDate;
}
let schedulerStart = new Date( startDate );
schedulerStart.setHours( schedulerStart.getHours() - 2 );
let schedulerEnd = new Date( endDate );
schedulerEnd.setHours( schedulerEnd.getHours() + 2 );
if( scheduler.startDate > schedulerStart && scheduler.endDate < schedulerEnd ){
scheduler.setTimeSpan( schedulerStart, schedulerEnd );
}
else if( scheduler.startDate > schedulerStart ){
scheduler.setStartDate( schedulerStart, false );
}
else if( scheduler.endDate < schedulerEnd ){
scheduler.setEndDate( schedulerEnd, false );
}
};
//simulate a rquest that pulls data from an external source
setTimeout(
() => {
loadData()
.then( () => {
console.log( "load data end" );
//simulate another rquest that pulls updated data
setTimeout(
async function(){
console.log( "udpate data start" );
await updateData();
console.log( "udpate data end" );
}
, 3000
)
});
}
, 3000
);
async function updateData(){
return scheduler.resourceStore.loadDataAsync( resources ).then( () => {
return scheduler.assignmentStore.loadDataAsync( assignments );
}).then( () => {
let loadDataPromise = scheduler.eventStore.loadDataAsync([
{
"id": "eventRecord1",
"name": "Task #1",
"startDate": new Date( 2021, 2, 3, 12, 0, 0 ),
"endDate": new Date( 2021, 2, 5, 18, 0, 0 )
}, {
"id": "eventRecord2",
"name": "Task #2",
"startDate": new Date( 2021, 2, 3, 13, 0, 0 ),
"endDate": new Date( 2021, 2, 5, 18, 0, 0 )
}
]);
loadDataPromise.then( _onEventStoreLoad );
return loadDataPromise;
});
}
</script>
</body>
</html>