Our state of the art Gantt chart


Post by devcat »

Hi,

We are implementing Live Updates in a web application with Angular 14 and .NET 8, Gantt version 6.0.4. Sending a revision with update works, but not when deleting a Task, for example.

Part of the object received with the 'revisionNotification' event and sent to the backend:

changes.tasks: {
 $input: { removed: [] }
 removed: [{ id: 103158 }]
}

We return the same object from the backend to the Angular client using SignalR, to then use it with applyRevisions(). Adding the id object in $input.removed, as we see in your example that the array is filled.

changes.tasks: {
 $input: { removed: [{ id: 103158 }] }
 removed: [{ id: 103158 }]
}

Error generated in Angular client after executing applyRevisions():

Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'id')
TypeError: Cannot read properties of undefined (reading 'id')
    at StoreBag.includes (gantt.module.js:24007:65)
    at TaskStore.applyRemovals (gantt.module.js:25135:24)
    at TaskStore.applyChangeset (gantt.module.js:25079:10)
    at TaskStore.applyChangeset (gantt.module.js:32423:52)
    at TaskStore.applyChangeset (gantt.module.js:203925:23)
    at ProjectModel3.applyChangeset (gantt.module.js:131712:34)
    at gantt.module.js:192803:8
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (asyncToGenerator.js:3:1)
    at _next (asyncToGenerator.js:25:1)
    at resolvePromise (zone.js:1211:31)
    at zone.js:1118:17
    at zone.js:1134:33
    at asyncGeneratorStep (asyncToGenerator.js:6:1)
    at _throw (asyncToGenerator.js:29:1)
    at _ZoneDelegate.invoke (zone.js:372:26)
    at Object.onInvoke (core.mjs:26231:33)
    at _ZoneDelegate.invoke (zone.js:371:52)
    at Zone.run (zone.js:134:43)
    at zone.js:1275:36

Thanks!


Post by Maxim Gorkovsky »

Hello.
You are not expected to modify the $input field. Task should either be removed by another change, or there is a bug. Could you provide more info on how you remove the task?

This exception in rather odd. It says that modelClass.idField (which is normally id) is not found in the object { id: 103158 }. Please check idField in your model class:

gantt.taskStore.modelClass.idField

or

gantt.taskStore.first.constructor.idField

.


Post by devcat »

If we change all "Id" in Angular client and backend to "id" then it works.

Using "Id" and also having "Id" in gantt.taskStore.modelClass.idField doesn't work, it seems like StoreBag or somewhere in your library uses "id".


Post by Maxim Gorkovsky »

Are you saying if you use such changeset with Id as idField then you see this exception?

changes.tasks: {
 $input: { removed: [{ Id: 103158 }] }
 removed: [{ Id: 103158 }]
}

Exception points to a line in code where we read idField from the model class. I cannot see how it would fail to get the Id key from the object. Can you try to debug it and see what's wrong?

In your case, apparently this line returns undefined:

// removedEntry is `{ Id: 103158 }`
// idDataSource should be `Id`
// id should be 103158 but it is undefined
const id = ObjectHelper.getPath(removedEntry, idDataSource);

The only reason I could think of is that modelClass.idField is not Id.

If you could make a runnable test case, or somehow reproduce it on our examples, we could take a look. You don't need any backend, the only thing you need is exact store configuration and to call the api store.applyChangeset({ removed: [{ Id: 'any id here, does not matter' }] })


Post by devcat »

Testing with your realtime-updates example (6.0.1), I added console.log() in a part of the code in \lib, specifically in the file \SchedulerPro\model\mixin\ProjectChangeHandlerMixin.js, line 164:

for (const data of storeChanges.removed ?? []) {
 console.log('afterApplyProjectChangesCleanup()', data.id, data.Id);
 store.removed.remove(data.id);
}

afterApplyProjectChangesCleanup() 4035 undefined

In our case we use "Id" and it would be "undefined". I understand that "data.id" in your code should be dynamic and take the value of modelClass.idField, for example: data[idField]


Post by Maxim Gorkovsky »

afterApplyProjectChangesCleanup() 4035 undefined

If you only log this and haven't updated model definition - it is an expected behavior.

Complete model definition would be:

class MyModel extends TaskModel {
  static fields = ['Id'];
  static idField = 'Id';
}

This is how it works for me:

Screenshot 2024-08-09 172104.png
Screenshot 2024-08-09 172104.png (148.99 KiB) Viewed 292 times

I understand that "data.id" in your code should be dynamic and take the value of modelClass.idField, for example: data[idField]

This is what we are doing, yes.

Could you please provide a runnable test case? Maybe modifying one of our vanilla demos to reproduce the issue.


Post Reply