Premium support for our pure JavaScript UI components


Post by imkookoo »

I have a "change" trigger setup against the eventStore / assignmentStore which triggers data to get sent to the backend to get saved. The problem I'm having is that when initializing the screen with all the initial schedule events, this trigger is being set off, causing there to be unnecessary updates to the backend database. Actually, it does it twice since I have it setup to save changes any time the assignments -or- the events change.

The frontend is adding the events like below to the Scheduler Pro instance:

this.schedulerPro.eventStore.add(this.schedulerEvents(i),
    true
    ); // I don't know how to quote square brackets in the forums, so I changed all the square brackets to paranthesis

In the API documentation, I see to send "true"
as the second argument to silence triggers,
but the trigger is still being set off.Using the web dev tools,
I stepped through this method,
and notice it 's going into "RecurringTimeSpansMixin" (I am using Recurring Times in the calendar).. But I noticed that the add function here doesn'
t have a second argument defined:

[code]
add(record) {
    ...
    return super.add(records);
}
[/code]
    
    Stepping into the "super.add"
    call, which goes to the "add"
    method in StoreStm.js,
    I see that that one does have the second argument defined:
    
    [code]
    add(records, silent = false) {[/code]

Is there any way I could get around this? I tried setting a property before and after the "add" calls up on top to suppressEvents just before the add, and then resumeEvents afterward, but that doesn't seem to work since the triggers seem to be executed afterward asynchronously.

Last edited by imkookoo on Wed Feb 24, 2021 4:29 am, edited 1 time in total.

Post by mats »

and notice it 's going into "RecurringTimeSpansMixin" (I am using Recurring Times in the calendar).. But I noticed that the add function here doesn'
t have a second argument defined:

This is a bug we recently fixed, you can try the latest nightly build perhaps to see if this behavior is gone. In general, you should not have to use suspendEvents, can you please share how you load your initial data?


Post by imkookoo »

Thank you, mats. I upgraded the Scheduler Pro and that resolved the issue.

I load the initial data after the initialization of Scheduler Pro via the following after the initialization of Scheduler Pro (and same for the assignmentStore):

this.schedulerPro.eventStore.add( < JSON
    for event here > , true);

I know I can do that also through the JSON passed into the Scheduler Pro initialization, but I have logic to also to dynamically fetch data for other days, which uses the same methods so I can consolidate the logic. The only store I populate at initialization time is the resourceStore.


Post by mats »

For setting a new dataset, this performs a bit better:

this.schedulerPro.eventStore.data = yourArray;

Post by imkookoo »

Awesome.. thank you for the tip!


Post by imkookoo »

So unfortunately, I'm still encountering this issue, and encounter another issue trying to fix it. I upgraded the SchedulerPro this morning, and that resolved the triggers being called when I'm first initializating the SchedulerPro instance, so I thought that did the trick. But:

The scheduler is shown by day in my app, and I have buttons that shift the scheduler by one day back/forward, which sends a request to the backend to retrieve the data for that day via AJAX call. When the data goes back to the front-end, I call eventStore.add / assignmentStore.add calls to add them to the scheduler:

this.schedulerPro.eventStore.add( < event JSON > , true);
this.schedulerPro.assignmentStore.add( < event assignment JSON > , true);

But even with the 2n d arg being true, the "change"
triggers on the assignment / event store are being executed.

So, I restructured the logic as you suggested,
and changed it so that I populate the eventStore /
assignmentStore by constructing an array of all the events /
assignments and adding them via "eventStore.data = <event array>" /
"assignmentStore.data = <event array>".

That seemed to do the trick.
.the triggers were no longer being called when shifting the days.

But, now I 'm running int another issue: I'
m also using a grid that has unscheduled events that users can drag - and -
drop from(I followed the dragfromgrid example).

What 's happening is that upon shifting the days, the "Unscheduled" grid gets updated with -all- of the events, even the ones that are assigned on the scheduler. If I manually execute "this.unplannedGrid.store.fillFromMaster()" after everything is done, the grid gets properly updated to only have the unscheduled events.

I tried debugging, putting a breakpoint inside the chain
function below:

    class UnplannedGrid extends top.viewFrame.bryntum.schedulerpro.Grid {
        ....
        set project(project) {
            this.store = project.eventStore.chain(function(eventRecord) {
                return !eventRecord.assignments.length
            });
            
            project.assignmentStore.on({
                change() {
                    this.store.fillFromMaster();
                },
                thisObj: this
            });
        }
    }
    
    this.unplannedGrid = new UnplannedGrid({
        ref: 'unplannedGrid',
        appendTo: 'schedulerDiv',
        flex: '1 0 565px',
        minWidth: '405px',
        project: this.schedulerPro.project
    });

From inside the chain function, that "assignments.length" value is 0 for the event, even though it is assigned. If I access the event after everything finishes, then the assignments.length for that event is 1. I'm guessing that the assignments inside the eventStore doesn't get evaluated until later or something. Is there a way around this?


Post by alex.l »

Hi imkookoo,

This approach won't work, because the SchedulerPro needs some time to do calculations. Please take a look at our guide:
https://bryntum.com/docs/scheduler-pro/#guides/data/storebasics.md#crud-operations

From the guide:
Please note that Scheduler uses a calculation engine to determine dates, durations and references between records. This engine operates asynchronously, thus the results of the calculations are not immediately available after CRUD operations. To make sure that results are available, either call await project.commitAsync() or use addAsync() or insertAsync().

Using project.commitAsync():

eventStore.add({
    startDate: '2020-09-15',
    duration: 2
});

// assignments, durations and some other data that needs calculations are not ready now

await eventStore.project.commitAsync();

// here you can use it!

Using addAsync():

await eventStore.addAsync({
    startDate: '2020-09-15',
    duration: 2
});

// Here you can update your grid with it's data

Same for assignmentStore. So please wait for both to make sure all data are ready.

All the best,
Alex

All the best,
Alex


Post by imkookoo »

Thanks Alex. I tried doing the addAsync way this morning, but was running into some Exceptions. I eventually got it to work by adding the events like Mats suggested, and calling unplannedGrid.store.fillFromMaster() manually after doing a "await this.schedulerPro.eventStore.commitAsync();"


Post by mats »

But even with the 2n d arg being true, the "change"
triggers on the assignment / event store are being executed.

@imkookoo: Any chance you can wrap this up in a small test case based on one of our samples so we can take a look?


Post by imkookoo »

Sure thing. I created a very rudimentary example, which should be attached to this posting.

Just put the example.html in a directory, create an "import" directory in that directory, with all the schedulerpro JS/CSS etc files in there. I was able to recreate with the 2/26 "release" nightly build.

The HTML will setup a scheduler... and then I make two sets of calls to add events: One right after the initialization of the scheduler, and one after a 3 second delay using setTimeout to simulate adding an event via AJAX some time later. Of course in the real application, this wasn't done in a setTimeout, but just a regular ajax call after a user changes the dates, which eventually runs the eventStore/assignmentStore.add method.

Also, instead of calling the method that sends the data to the backend to get saved, I replaced those with window.alert's showing which event gets triggered.

Anyways, upon loading the page, the first event gets added, and no triggers are triggered, as expected. But when the second event gets added, a few seconds later, the change/update trigger is set off.

I've since switched using the method you suggested, and that's working fine without firing the triggers in either case. But hope this helps with any troubleshooting if somebody does it this way.

Attachments
example.zip
(3.77 KiB) Downloaded 71 times

Post Reply