We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
close icon

Vue scheduler does not refresh when dataSource is updated

After calling an API, I update the datasource for the scheduler with the response, yet none of the events render on the page.


<template>
<div>
<div id="calendar-content">
<div class="calendar-holder">
<ejs-schedule height="650px"
id="schedule"
ref="ScheduleObj"
:selectedDate='selectedDate'
:eventSettings='eventSettings'
:views='views'
></ejs-schedule>
</div>
</div>
</div>
</template>

<script>
import { SchedulePlugin, Day, Month, Agenda, Resize, DragAndDrop } from "@syncfusion/ej2-vue-schedule";
import { extend } from '@syncfusion/ej2-base';
import Events from '@/services/events'

import Vue from 'vue'
Vue.use(SchedulePlugin);

const eventTemplate = {
Id: -1,
Subject: '',
StartTime: new Date(),
EndTIme: new Date(),
IsAllDay: false,
}

export default {
name: 'Calender',
data() {
return {
events: [],
eventSettings: { dataSource: extend([{}], this.events, null, true)},
selectedDate: new Date("2018-08-19T12:00:00"),
views: ['Month', 'Day', 'Agenda'],
}
},
provide: {
schedule: [Day, Month, Agenda, Resize, DragAndDrop]
},
mounted() {
this.getEvents()
},
methods: {
async getEvents () {
const response = await Events.getEvents()
const data = response['event(s)']
for (let index = 0; index < data.length; index++) {
const event = data[index];
this.events.push({
Id: event.id,
Subject: event.eventName,
StartTime: new Date(event.startTime),
EndTIme: new Date(event.endTime),
})
}
this.eventSettings.dataSource = this.events
}
},
}
</script>




The data is being passed into the component as the screen shot below shows.
It is just not rendering

24 Replies

VD Vinitha Devi Murugan Syncfusion Team May 1, 2019 08:04 AM UTC

Hi Harrison, 
 
Greetings from Syncfusion Support. 
 
We have checked the reported scenario by preparing a sample based on your shared code, and we are able to reproduce the issue. we suggest you use the below highlighted code to overcome the issue. 
 
    async getEvents () { 
      const response = await Events.getEvents() 
      const data = response['event(s)'] 
      for (let index = 0; index < data.length; index++) { 
        const event = data[index]; 
        this.events.push({ 
          Id: event.id, 
          Subject: event.eventName, 
          StartTime: new Date(event.startTime), 
          EndTIme: new Date(event.endTime), 
        })         
      } 
      //this.eventSettings.dataSource = this.events  
      let scheduleObj = document.getElementById("Schedule").ej2_instances[0]; 
      scheduleObj.eventSettings.dataSource = this.events 
    } 
 
Kindly use the above suggested way and let us know, if it resolves your problem and also, if you need any further assistance on this 
 
Regards,  
M. Vinitha devi. 
 



HH Harrison Haigler May 1, 2019 05:01 PM UTC

Thanks for the quick response! I tried it and it still does not work. The component seems to have all the correct info yet it is not rendering.



KK Karthigeyan Krishnamurthi Syncfusion Team May 2, 2019 11:29 AM UTC

Hi Harrison,  
 
Thanks for your update. 
 
We suspect that using this could be the cause for the issue. We have prepared the below sample to update the data source on button click. 
 
onSubmit: function() { 
let scheduleObj = document.getElementById("Schedule").ej2_instances[0]; 
scheduleObj.eventSettings.dataSource = [{ 
Id: 1, 
Subject: 'Explosion of Betelgeuse Star', 
StartTime: new Date(2018, 5, 4, 9, 30), 
EndTime: new Date(2018, 5, 4, 11, 0), 
}, 
{ 
Id: 2, 
Subject: 'Analysis', 
StartTime: new Date(2018, 5, 4, 9, 30), 
EndTime: new Date(2018, 5, 4, 11, 0), 
}]; 
} 
 
 
Regards, 
Karthi 



HH Harrison Haigler May 15, 2019 06:57 PM UTC

This is still not working. It will only work it the data source array is explicitly declared in the function. It does not work if the array is loaded in from an API.


KK Karthigeyan Krishnamurthi Syncfusion Team May 16, 2019 06:24 AM UTC

Hi Harrison,   
  
Thanks for your update.  
 
We have checked the reported case and remote API data is rendered in Schedule on button click. 
 
onSubmit: function() { 
  let scheduleObj = document.getElementById("Schedule").ej2_instances[0]; 
  var dataManger = new DataManager({ 
    url: "https://js.syncfusion.com/demos/ejservices/api/Schedule/LoadData", 
    adaptor: new WebApiAdaptor(), 
    crossDomain: true 
  }) 
    .executeQuery(new Query().take(100)) 
    .then(e => { 
      scheduleObj.eventSettings.dataSource = e.result; 
    }); 
} 
 
Kindly try the sample and if the issue persists, try to reproduce the error in a sample and revert else share your code example/runnable sample (if possible) to serve you better. 
 
Regards, 
Karthi 



HH Harrison Haigler May 16, 2019 05:41 PM UTC

I got it working! However I had to do quite a few workarounds. I figured out the issue is that if the dataSource has an observer on it then the scheduler will reject it (example below). Can y'all fix this so we don't have to hack around it. Also, instead of needing to look up the element by it's element id, it would be great to just change the dataSource that is passed to the component.

This works:


This does not: 



KK Karthigeyan Krishnamurthi Syncfusion Team May 17, 2019 07:06 AM UTC

Hi Harrison,    
   
Thanks for your update. 
 
We have checked the reported case and observer datasource working fine with addEvent. Kindly try to reproduce the error in a sample and revert else share your code example/runnable sample (if possible) to serve you better. 
 
If you wish to share your files in private, please create the incident. 
 
Regards, 
Karthi 



CT Caxer Tsang June 20, 2019 03:07 AM UTC

I have same issue here, I fix this problem with clearing the existing array and pushing new data in it. Assigning new array will not update the events.


KK Karthigeyan Krishnamurthi Syncfusion Team June 20, 2019 03:31 AM UTC

Thanks for your suggestion 😊 



HH Harrison Haigler July 8, 2019 08:40 PM UTC

Thanks for the solution!


KK Karthigeyan Krishnamurthi Syncfusion Team July 9, 2019 03:41 AM UTC

Most welcome 😊 



AD Adam August 1, 2020 01:57 AM UTC

Was there ever a good resolution to this? I feel like the scheduler should simply update when the reactive variable is updated. I am having the same problem (even a year later), and am unsure how best to handle it. The solutions posted by support here seem awfully hacky.


VM Vengatesh Maniraj Syncfusion Team August 3, 2020 11:30 AM UTC

Hi Adam, 

Greetings from Syncfusion Support. 

We checked your requirement and we suggest you please change the eventSetting variable like the below code snippet to achieve your requirement. 

onSubmit: function() { 
   this.eventSettings = { dataSource: this.generateData() }; 
} 


Kindly check the above sample and get back to us if you need any further assistance. 

Regards, 
Vengatesh  



TB Tomasz Bednarek August 18, 2020 10:01 AM UTC

Hi Syncfusion,

Yes, this works, although I've lost quite a few hours finding this solution. Please update the documentation or make the .refresh() and/or refreshEvents() methods work, because many people may stumble uppon this. Adding an event with .addEvent(...) and the calling any refresh method also doesn't work, so what's the use of those methods in the Vue version anyway?

Kind Regards
Tomasz


BS Balasubramanian Sattanathan Syncfusion Team August 19, 2020 01:32 PM UTC

Hi Tomasz Bednarek, 

Thanks for the date. 

We have validated your reported scenario at our side and let you know that the refresh method is used to only refresh the Schedule UI and refreshEvents method is used to refresh the events alone and it will be suited for the Vue framework too. If we add the new appointment in the Scheduler by using the addEvent method, we can use the refresh method to reflect the changes in the DOM if the event is not added in the DOM. We would suggest you to refer the below UG links. 


Please let us know if you need further assistance. 

Regards, 
Balasubramanian S 



RB Ronald Bradley October 25, 2020 04:39 PM UTC

You can create a new data property and set it and the eventSettings.dataSource to the same object. Then create a "deep watcher" for the data property and update the eventSettings object so that Scheduler knows the dataSource has changed. Although this causes a weird pause as the whole scheduler is rerendered. There has to be a better way.

let data = []

export default {
data() {
return {
eventSettings: {
dataSource: data,
},
dataSource: data,
}
},
watch: {
dataSource: {
deep: true,
handler(e) {
this.eventSettings = {...this.eventSettings}
}
}
}, }


RB Ronald Bradley October 26, 2020 12:21 AM UTC

Okay, I figured it out. You have to make dataSource reactive. So, leave it out of the component data and then create it in mount (or maybe created)

const data = [{
id: 1,
name: 'Paris',
startTime: new Date(2020, 9, 25, 1, 0),
endTime: new Date(2020, 9, 25, 2, 0),
}]


export default {
name: 'App',
data() {
return {
eventSettings: {},
}
},
mounted() {
this.$set(this.eventSettings, 'dataSource', [])
this.eventSettings.dataSource.push(...data)
}
}







BS Balasubramanian Sattanathan Syncfusion Team October 26, 2020 08:14 AM UTC

Hi Ronald, 

Thanks for the reply. 

We have analyzed your reported scenario at our end and checked by preparing the sample based on your code snippet. We let you know that the dataSource is added properly in the Schedule. So we would suggest you to refer and follow the below sample. 

let timelineResourceData = [ 
  { 
    Id: 1, 
    Subject: "Decoding", 
    StartTime: new Date(2018, 1, 12, 11), 
    EndTime: new Date(2018, 1, 12, 13), 
    IsAllDay: false 
  } 
]; 
 
export default Vue.extend({ 
  data: function() { 
    return { 
      eventSettings: {}, 
      selectedDate: new Date(2018, 1, 15) 
    }; 
  }, 
  provide: { 
    schedule: [Day, Week, WorkWeek, Month, Resize, DragAndDrop] 
  }, 
  mounted() { 
    this.$set(this.eventSettings, 'dataSource', []) 
    this.eventSettings.dataSource.push(...timelineResourceData) 
  } 
}); 


Kindly try the above sample and let us know the below details if the problem is not resolved. 
  • Replicate your problem in the above samples and share the replication steps or
  • Share a sample illustrating the problem which would help us to provide the solution at the earliest

Regards, 
Balasubramanian S


RB Ronald Bradley October 26, 2020 06:01 PM UTC

A problem arises when I add resources to the the component. I get console errors:

[Vue warn]: Error in callback for watcher "eventSettings": "TypeError: Cannot read property 'startDate' of undefined"
TypeError: Cannot read property 'startDate' of undefined 




Ugh! Is there no way to make eventSettings.dataSource reactive like a normal Vue component?


RB Ronald Bradley October 26, 2020 07:00 PM UTC

Why does document.querySelector("#scheduler").ej2_instances[0].eventSettings.dataSource show the events, but not the component's this.eventSettings.dataSource ?



SK Satheesh Kumar Balasubramanian Syncfusion Team November 3, 2020 12:31 PM UTC

Hi Ronald, 
  
Thanks for your update. 
  
Q1:  We have validated your reported problem "A problem arises when I add resources to the the component. I get console errors" and could reproduce the issue at our end. In resource sample, promise will be resolved slower compared to default sample. Therefore, we are facing reported issue. Kindly use dataBound event as below to resolve issue. Please refer the below snippet. 
  
    :dataBound="onDataBound" 
         
   flag: true, 
  
  methods: { 
    onDataBound: function (event) { 
      if (this.flag) { 
        this.$set(this.eventSettings, "dataSource", []); 
        this.eventSettings.dataSource.push(...timelineResourceData); 
        this.flag = false; 
      } 
    }, 
  
Sample can be available in the following link. 
  
  
Q2: Why does document.querySelector("#scheduler").ej2_instances[0].eventSettings.dataSource show the events, but not the component's this.eventSettings.dataSource ? 
  
We validated your reported issue but at our end, but this.eventSettings.dataSource shows the event details in console. Please refer below image. 

 
  
Kindly try the above sample and get back to us, If you need further assistance. 
  
Regards, 
Satheesh Kumar B 



January 17, 2021 08:23 PM UTC

In Vue reactivity does not monitor certain changes to an array (see Reactivity for arrays).

Im not sure how SyncFusion works under the hood, since I would assume a direct assignment should work without issues, but it doesn't and here is my solution that seems to work:
  1. return event settings as a computed property
  2. Use spread syntax as an assignment to dataSource

eventSettings () {
      return {
        enableMaxHeight: true,
        dataSource: [ ...this.myDataSource ],
        fields: {
          id: 'id',
          subject: { name: 'availabilityStatus' },
          startTime: { name: 'startDateTime' },
          endTime: { name: 'endDateTime' }
        }
      }
    },




January 17, 2021 08:41 PM UTC

I should add that the scheduler component should NOT be returning errors in its watcher if a datasource has not yet been provided, it should simply cancel any attempt to bind. Instead perhaps it should report the error as a log when debugging is enabled (if there is such a thing).

In our case we do still want to show the component even if there is no data to bind, but would be good not to have the console errors on an initial load.


BS Balasubramanian Sattanathan Syncfusion Team January 18, 2021 12:13 PM UTC

Hi James, 
 
Thanks for contacting Syncfusion Support. 
 
We have validated your requirement at our end and prepared a sample based on that by using the below code snippet. And we let you know that there is no error has been occurred on initial loading and also we can show the schedule component even there is no data to bind. In the below sample, we have empty the dataSource in the dataBound event for your reference. 
 
computed: { 
    eventSettings() { 
      return { 
        dataSource: [...this.events], 
        fields: { 
          id: "id", 
          subject: { name: "subject" }, 
          startTime: { name: "startTime" }, 
          endTime: { name: "endTime" }, 
          isAllDay: { name: "isAllDay" } 
        } 
      }; 
    } 
} 
 
 
 
Kindly refer to the above sample and let us know the below details if it doesn’t meet your requirement. 
  • Share your use case scenario with details.
  • Try to reproduce the problem(if exist) with the above sample
  • Share a video/image/sample illustrates of your requirement.
 
Regards, 
Balasubramanian S 


Loader.
Live Chat Icon For mobile
Up arrow icon