Our pure JavaScript Scheduler component


Post by Cr3aHal0 »

Hello everyone,

First of all, thanks for this great tool ! My company was already using its ExtJS version and finally made the jump to the VanillaJS one to usee it within Angular views.

I dug deep in the official doc but I could not find any answer to my problem that is : I recently got an error in some components that host the Scheduler wrapper you provide in your samples stating :
Uncaught TypeError: Cannot read property 'resourceStore' of null
which is called around those lines :
    setResources(resources: ResourceModel[], silent: boolean = false) {
        if (this.schedulerEngine.resourceStore) {
            this.schedulerEngine.resourceStore.removeAll(silent)
            this.schedulerEngine.resourceStore.add(resources, silent)
        }
    }
The message is pretty clear as it seams that the "this.schedulerEngine" is not set yet (as it is defined into the "ngOnInit" Angular lifecycle hook), but what disturbs me is that my "setResources" function is called after "ngAfterViewInit" which should mean every child component has been rendered, thus the Scheduler should be rendered and ready to go, shouldn't it ?

The reference to your SchedulerComponent wrapper is done as followed :
  @ViewChild(Scheduler, {static: false}) scheduler: Scheduler;
I am then wondering if there is a step I may have missed or if it should work plain simple ? If this should work with that few details, I would like to know if you have any lifecycle hooks provided by your library which would allow devs to listen for the "ready" state of the Scheduler (and thus the schedulerEngine being properly defined)

Thanks in advance for your help, and have a great day

Max

Post by saki »

Here are some thoughts that could explain the timing/lifetime
  1. the application (app.component) uses our component in template as '<bry-scheduler ....></bry-scheduler>'
  2. that means that nothing of the scheduler runs before Angular starts to use this template
  3. the template and therefore also our scheduler. has not yet been initialized during `ngOnInit` of `app.component`.
  4. in the wrapper (../_shared/.../lib/scheduler.component.ts) we create instance of the scheduler as early as possible (as early as we have the element) in `ngOnInit`
  5. then, in `ngAfterViewInit`, the engine already exists – this is the first moment in the application when the engine can be used.
If you want to test it, use our animations demo and place some console.logs in the code:

/**
 * Runs after the view (including the child scheduler) is initialized
 */
ngAfterViewInit() {
    console.log(`ngAfterViewInit schedulerEngine: `, this.scheduler.schedulerEngine);
    this.setAnimationDuration(600);
}

/**
 * Runs on this component initialization
 */
ngOnInit() {
    console.log(`ngOnInit schedulerEngine: `, this.scheduler.schedulerEngine);
    document.head.appendChild(this.styleNode);
}
Emitting an event when schedulerEngine is defined is quite easy too. Just put you own eventEmitter in ../_shared/.../lib/scheduler.component.ts and emit the event after line:
const engine = this.schedulerEngine = new Scheduler(config);
Although this can be done, I think that implementing `ngAfterViewInit` is easier.

Post by Cr3aHal0 »

Hi,

Thank you for your quick response ! Definitely chose the ngAfterViewInit way, works fine :)

Have a good day !

Post Reply