Our state of the art Gantt chart


Post by inspire »

Hi!

We have node.js app working as Gantt scheduler getting data and returning recalculated project changes.
With some data it throws exception which is not catched in try - catch block and app crashes.
This is error stack we get:

Uncaught TypeError TypeError: startDateIntervalIntersection.intersectionOf is not iterable
at calculateEffectiveEndDateConstraintInterval (node_modules/@bryntum/gantt/gantt.node.mjs:44471:58)
at calculateEffectiveConstraintInterval (node_modules/@bryntum/gantt/gantt.node.mjs:44575:40)
at doCalculateEffectiveEndDateInterval (node_modules/@bryntum/gantt/gantt.node.mjs:44607:26)
at onEmptyEffectiveInterval (node_modules/@bryntum/gantt/gantt.node.mjs:45850:142)
at onEmptyEffectiveInterval (node_modules/@bryntum/gantt/gantt.node.mjs:48546:29)
at calculateEndDate (node_modules/@bryntum/gantt/gantt.node.mjs:44719:41)
at continueCalculation (node_modules/@bryntum/gantt/gantt.node.mjs:1088:49)
at onReadIdentifier (node_modules/@bryntum/gantt/gantt.node.mjs:2507:26)
at calculateTransitionsStackGen (node_modules/@bryntum/gantt/gantt.node.mjs:2627:47)
at calculateTransitions (node_modules/@bryntum/gantt/gantt.node.mjs:2540:19)
at runGeneratorAsyncWithEffect (node_modules/@bryntum/gantt/gantt.node.mjs:1189:23)
gantt.node.mjs:44471
Process exited with code 1

Our code:

try {
...
            const ganttProject = new GanttProject();
            let project = ganttProject.init(projectData);

        const result = await project.commitAsync();
        if (result.rejectedWith) {
            // there was a conflict during the scheduling
            console.log(result);
        } else {
...
            }
        } catch (err) {
            console.error(err);
            res.send({ success: false, message: err.message });
        }

When we open same project in Gantt UI we get "Scheduling conflict" message. but no "rejectedWith" result in our service app.


Post by mats »

That sounds strange. Any chance you can share a test case? What version are you using?


Post by inspire »

This file contains project data json that causes error.
https://drive.google.com/file/d/1xFalM6UUPlpkko3tOw_MBu0w6GTtGd7S/view?usp=sharing

Bryntum Gantt ver. 6.1.7


Post by tasnim »

Hey inspire,

I cannot reproduce the behavior with your data (Version 6.2.1).

chrome_AR2A59lIBM.png
chrome_AR2A59lIBM.png (133.12 KiB) Viewed 585 times

Could you please try with the latest version and see if you can reproduce there?

Best regards,
Tasnim

How to ask for help? Please read our Support Policy


Post by inspire »

Hi!

Yes, you did not get the error because you did not include our pre-load processing for tasks data; I did try with latest version and it throws error too.
This is processing code

const mapTasks = (that, records, completedString, honorProjectBorders) => {
    let newRecords = [];
    let startDate, endDate;
    if (records != null) {
        records.forEach(record => {
            let newRecord = { ...record };

        for (let f of ['sequenceNumber', 'wbsCode', 'childLevel']) {
            if (newRecord[f]) {
                newRecord[f + 'Original'] = newRecord[f];
                delete newRecord[f];
            }
        }
        newRecord.projectConstraintResolution = honorProjectBorders ? 'honor' : that.projectConstraintViolation;
        if (newRecord.status == completedString) newRecord.manuallyScheduled = true;
        newRecord.startDate = newRecord.startDate ? newRecord.startDate.substring(0, 19) : undefined;
        newRecord.endDate = newRecord.endDate ? newRecord.endDate.substring(0, 19) : undefined;
        newRecord.constraintDate = newRecord.constraintDate ? newRecord.constraintDate.substring(0, 19) : undefined;
        newRecord.baselineStartDate = newRecord.baselineStartDate ? newRecord.baselineStartDate.substring(0, 19) : undefined;
        newRecord.baselineEndDate = newRecord.baselineEndDate ? newRecord.baselineEndDate.substring(0, 19) : undefined;
        newRecord.actualStartDate = newRecord.actualStartDate ? newRecord.actualStartDate.substring(0, 19) : undefined;
        newRecord.actualFinishDate = newRecord.actualFinishDate ? newRecord.actualFinishDate.substring(0, 19) : undefined;
        newRecord.finishDate = newRecord.finishDate ? newRecord.finishDate.substring(0, 19) : undefined;
        if (newRecord.baselines) {
            newRecord.baselines.forEach(b => {
                if (b) {
                    b.startDate = b.startDate ? b.startDate.substring(0, 19) : undefined;
                    b.endDate = b.endDate ? b.endDate.substring(0, 19) : undefined;
                }
            });
        }

        if (newRecord.startDate && (!startDate || new Date(newRecord.startDate.substring(0, 10)) < new Date(startDate))) startDate = newRecord.startDate.substring(0, 10);
        if (newRecord.endDate && (!endDate || new Date(newRecord.endDate.substring(0, 10)) > new Date(endDate))) endDate = newRecord.endDate.substring(0, 10);

        if (!newRecord.actualEffortUnit) newRecord.actualEffortUnit = 'h';

        if (!that._startDate || (newRecord.startDate && DateHelper.parse(newRecord.startDate) < DateHelper.parse(that._startDate))) that._startDate = DateHelper.parse(newRecord.startDate);
        if (!that._endDate || (newRecord.startDate && DateHelper.parse(newRecord.endDate) > DateHelper.parse(that._endDate))) that._endDate = DateHelper.parse(newRecord.endDate);

        newRecord.children = mapTasks(that, record.children, completedString, honorProjectBorders).tasks;
        newRecords.push(newRecord);
    });
}
newRecords.sort((a, b) => a.sequenceNumberOriginal - b.sequenceNumberOriginal);
return { startDate: startDate, endDate: endDate, tasks: newRecords };
}

Function result tasks property is loaded to ProjectModel. When I turned off this mapping error disappeared and I got correct "rejectedWith" result.


Post by tasnim »

Where should I call the function reproduce? And what are the parameters value I should use to reproduce it?

Best regards,
Tasnim

How to ask for help? Please read our Support Policy


Post by inspire »

Hi!

        this.projectData = JSON.parse(JSON.stringify(projectData).replaceAll('"b_from"', '"from"')); // projectData is exactly from request I gave link above 
	// this.honorProjectBorders is calculated as FALSE in this case
        const tasksData = mapTasks(this, this.projectData.tasks, this.projectData.completedString, this.honorProjectBorders);
        this.isProjectSchedulingAutoMode = this.projectData.project.inspire1__Scheduling_Mode__c === 'Automatic';

    this.project = new ProjectModel({
        tasksData: tasksData.tasks, // result from mapTasks
        dependenciesData: this.projectData.dependencies,
        addConstraintOnDateSet: this.isProjectSchedulingAutoMode,
        includeAsapAlapAsConstraints: this.isProjectSchedulingAutoMode,
...
            },
        });

Post by tasnim »

Hi,

Sorry for the late reply. The code you shared is not runnable for us.

Could you please share a runnable test case so we can download it locally and see what's wrong?

Best regards,
Tasnim

How to ask for help? Please read our Support Policy


Post by inspire »

Hi!

Link to heroku app zip that gets exception https://drive.google.com/file/d/1bxbh5ExVUy8M4D65o-_pPeQlV8821hjU/view?usp=sharing.
I have placed sample project data into bryntum/request folder.


Post by tasnim »

Thanks for sharing the test case. How can we run it? I tried running with npm i and npm start

inspireplanner-data-service@0.1.0 start
node index.js

{}
env undefined
Listening on 5001

From that, I opened a tab for this path http://localhost:5001/ but it shows Cannot GET /

Am I missing something?

Best regards,
Tasnim

How to ask for help? Please read our Support Policy


Post Reply