How to dynamically refresh/display API data on Schedule without using DataManager

Hi there

We use React Schedule component to display API data, and we need to load in new data when user navigate to another date.

This works fine when the page first loads, but as user navigates, new API call is made, but data won't populate. We have our own lib to fetch & cache data, so in order to keep our structure & caching consistent, we would not use DataManager unless there's no other choices. Is there a way to do this without using DataManager?

This is the code we have (simplified version)

function CalendarView() {
const [calendarData, setCalendarData] = useState([])
const [selectedDate, setSelectedDate] = useState(new Date())

const data = useActivities(selectedDate) // a hook that fetch new data when new date is passed in

useEffect(() => {
if (data) {
setCalendarData(transformData(data)) // @transformData method simply transforms API data into calendar format
}
}, [data])
const onNavigating = args => {
if (args.action === 'date') {
setSelectedDate(args.currentDate)
}
}

return (
<ScheduleComponent
eventSettings={{ dataSource: calendarData }}
currentView="Month"
selectedDate={selectedDate}
navigating={onNavigating}
>
<Inject services={[Day, Week, Month]} />
ScheduleComponent>
)
}


Any help would be very appreciated, thank you in advance!!!


9 Replies 1 reply marked as answer

BS Balasubramanian Sattanathan Syncfusion Team January 24, 2022 08:07 AM UTC

Hi Shan,

Greetings from Syncfusion Support.

We would suggest you to refer and follow the below forum link to have the Scheduler with CRUD actions without using DataManager.

https://www.syncfusion.com/forums/172013/react-scheduler-remote-data-from-api-not-showing-on-schedule?reply=S8Z8eu

Kindly let us know if you need further assistance.

Regards,
Balasubramanian S



SD Shan Du January 25, 2022 11:28 PM UTC

Hi Bala, thank you for the reply!!

The solution you presented works well if the data refetching is triggered from a Schedule event (e.g. `actionBegin`, `navigating`, etc.) but what if I need to refresh the data on an event outside of Schedule component?

For example, if there's a filter user can select which would reload the events data on the current calendar view, this would not trigger any Schedule component event, but would you recommend that I use the same approach here? 

e.g. run the following 2 lines after the data refetch

const calendarObj = document.querySelector('.e-schedule').ej2_instances[0]
calendarObj.eventSettings.dataSource = data


Lastly, would document.querySelector('.e-schedule').ej2_instances[0] yield the same object as `schObj` if it were set via a ref like this:

<ScheduleComponent ref={r => schObj = r} />


BS Balasubramanian Sattanathan Syncfusion Team January 26, 2022 07:19 AM UTC

Hi Shan,

Yes, you can use the same proposed solution or you can refresh the Scheduler appointments using refreshEvents method outside of the Scheduler component. And also we would suggest you to addEvent method to add the dynamic appointments to the Scheduler, saveEvent method for updating the existing appointments, and deleteEvent method for removing the appointments of the Scheduler.

Regards,
Balasubramanian S



SD Shan Du January 26, 2022 03:43 PM UTC

Thank you so much for the quick response & the links Bala!!! I actually did try using `refreshEvents` but it didn't seem to work, that's why I was asking the question here to begin with, but maybe I didn't use it properly.

  1. Do you have any code examples showing the proper way to use `refreshEvents` tho?
  2. Also do you recommend to always use `addEvent` `deleteEvent` & `saveEvent` when managing events?
  3. Lastly, are these two following objects actually equivalent?

document.querySelector('.e-schedule').ej2_instances[0] 

and

the `r` in  <ScheduleComponent ref={r => schObj = r} />


Thank you in advance!



BS Balasubramanian Sattanathan Syncfusion Team January 27, 2022 12:59 PM UTC

Hi Shan,

Thanks for the reply.

I actually did try using `refreshEvents` but it didn't seem to work, that's why I was asking the question here to begin with, but maybe I didn't use it properly.

​Can you please share your scheduler-related entire code snippet? which will be helpful to validate why refreshEvents not working in your case. 

Do you have any code examples showing the proper way to use `refreshEvents` tho?

You can refresh the events like below code snippet.

Sample: https://stackblitz.com/edit/react-96mmts?file=index.js

Code snippet:

onRefresh() {

  this.scheduleObj.refreshEvents();

  this.buttonObj.element.setAttribute('disabled''true');

}


Also do you recommend to always use `addEvent` `deleteEvent` & `saveEvent` when managing events?

Yes, we would suggest to use those public methods when the requirement is needed to do CRUD actions dynamically. Can you please refer to the below UG to know more details?

UG: https://ej2.syncfusion.com/react/documentation/schedule/crud-actions/

Lastly, are these two following objects actually equivalent?


Yes. We would say both are the same and have the same Scheduler element and its properties. But whenever you use this.scheduleObj it will have the value of the Scheduler based on this object. But if you use document.querySelector('.e-schedule').ej2_instances[0] it will have the value of the latest scheduler which has been rendered in the DOM.

Kindly let us know if you need further assistance.


Regards,
Balasubramanian S



SD Shan Du January 27, 2022 06:41 PM UTC

Thank you so much again for the quick response Bala, I gave `refreshEvents()` method another try but still didn't work, maybe it's due to the new React way of using `useEffect`, I'm not sure, here's a very simplified example of the code I have to demostrate how I attempted to use `refreshEvent` to refresh data:

function CalendarView() {
const [calRef, setCalRef] = useState() // calendar ref
const [filters, setFilters] = useState({
// 2022 Jan 1
startDate: new Date(2022, 0, 1, 10, 0, 0), // 2022-01-01 10:00:00
endDate: new Date(2022, 0, 1, 11, 0, 0), // 2022-01-01 11:00:00
})

const { data } = useFetchEvent(filters) // hook that fetch event data every time filters change

useEffect(() => {
if (data && calRef) {
// this is executed every time data changed
console.log('data is changed, run refresh, data = ', data)
calRef.refreshEvents() // <-- This does not work
}
}, [data, calRef])

const updateFilters = () => {
setFilters({
// 2022 Feb 1
startDate: new Date(2022, 1, 1, 10, 0, 0), // 2022-02-01 10:00:00
endDate: new Date(2022, 1, 1, 11, 0, 0), // 2022-02-01 11:00:00
})
}

return (
<>
<button onClick={updateFilters}>Update 2022 Feb Databutton>
<ScheduleComponent
eventSettings={{ dataSource: data }}
views={['Day', 'Week', 'Month']}
currentView="Month"
ref={setCalRef}
>
<Inject services={[Day, Week, Month]} />
ScheduleComponent>
)
}


that said, I did have success in the previous way you mentioned, altho the code above is the preferred approach since that's generally how we fetch/update data everywhere else in the app (via hooks & useEffect)

but if you think it won't work like this, it's also fine, we'll just go for the previous approach



SK Satheesh Kumar Balasubramanian Syncfusion Team January 28, 2022 12:20 PM UTC

Hi Shan, 
  
We have prepared sample to refresh the events based on the shared code snippets. 
  
  
child.js:    
const _scheduleData = [ 
  { 
    Id: 1, 
    Subject: 'Meeting - 1', 
    StartTime: new Date(2022, 0, 1, 10, 0, 0), // 2022-01-01 10:00:00 
    EndTime: new Date(2022, 0, 1, 11, 0, 0), // 2022-01-01 11:00:00 
  }, 
]; 
function Schedule() { 
  const [calRef, setCalRef] = useState(); // calendar ref 
  const [filters, setFilters] = useState(_scheduleData); 
  
  const [data, setScheduleData] = useState(filters); 
  
  useEffect(() => { 
    if (data && calRef) { 
      // this is executed every time data changed 
      console.log('data is changed, run refresh, data = ', data); 
      calRef.refreshEvents();  
    } 
  }, [data, calRef]); 
  
  const updateFilters = () => { 
    let data = [ 
      { 
        Id: 2, 
        Subject: 'Meeting - 2', 
        StartTime: new Date(2022, 1, 1, 10, 0, 0), // 2022-02-01 10:00:00 
        EndTime: new Date(2022, 1, 1, 11, 0, 0), // 2022-02-01 11:00:00 
      }, 
    ]; 
    setScheduleData(data); 
  }; 
  return ( 
    <> 
      <button onClick={updateFilters}>Update 2022 Feb Databutton</button> 
      <ScheduleComponent 
        eventSettings={{ dataSource: data }} 
        views={['Day', 'Week', 'Month']} 
        currentView="Month" 
        ref={setCalRef} 
      > 
        <Inject services={[Day, Week, Month]} /> 
      </ScheduleComponent> 
    </> 
  ); 
} 
  
Kindly try the above sample and let us know if this works at your end. If you still face any problem, replicate the issue in above sample (or) share issue replicating sample(if possible) which will help us to validate the issue and provide prompt solution as soon as possible. 
  
Regards, 
Satheesh Kumar B 


Marked as answer

SD Shan Du January 31, 2022 07:29 PM UTC

oh heyyyyyy, it's working now after cross-referencing my existing code with your solution!!!!!!

I think it's likely that I had some small & stupid mistakes before that I overlooked because I really didn't change a whole lot of code.


Anyways, thank you SOOOO much Satheesh for helping me out along the way! Fantastic support!

I'll mark the above as answer, although previous solutions provided would also work as well!



VM Vengatesh Maniraj Syncfusion Team February 1, 2022 03:41 AM UTC

You are most welcome Shan!!!

We are happy that our solution has worked for you.


Loader.
Up arrow icon