Diagram not up-to-date when "FinishedUndo" ChangeEvent is fired

I want to perform a certain action on the diagram after the user has performed an Undo/Redo.

In order to do so, I currently listen to a Model ChangedEvent:

e.change === go.ChangedEvent.Transaction &&
            (e.propertyName === "FinishedUndo" || e.propertyName === "FinishedRedo")

However, when adding a new node and then undoing this action, in the event listener:

  • the diagram still contains the added node in diagram.nodes (even though the node should be removed by undo)
  • the node.data is null

I assume this is by design? The diagram is not expected to be in sync with the model in the UndoFinished Model ChangedEvent?
If so, how can I listen to an undo/redo event and access a diagram which already contains all undo/redo changes?

I’m sorry, but I’m not getting that behavior.

I just took a random sample that I had lying around and added this listener:

  $(go.Diagram, . . .,
      "ModelChanged": e => {
        if (e.isTransactionFinished) {
          console.log(e.propertyName, e.model.nodeDataArray.length, myDiagram.nodes.count);
          myDiagram.nodes.each(node => console.log(node.data));
        }
      },
      "undoManager.isEnabled": true
    })

I first selected all two nodes and copy-and-pasted them, resulting in four nodes. Then I did an undo and then a redo. The results were as expected:

CommittedTransaction 4 4
Object { key: 1, text: "hello", color: "green", location: "0 0", __gohashid: 725, loc: "19.5 13" }
Object { key: 2, text: "world", color: "red", location: "70 0", __gohashid: 726, loc: "91 13" }
Object { key: -3, text: "hello", color: "green", location: "0 0", __gohashid: 840, loc: "19.5 13" }
Object { key: -4, text: "world", color: "red", location: "70 0", __gohashid: 848, loc: "91 13" }
FinishedUndo 2 2
Object { key: 1, text: "hello", color: "green", location: "0 0", __gohashid: 725, loc: "19.5 13" }
Object { key: 2, text: "world", color: "red", location: "70 0", __gohashid: 726, loc: "91 13" }
FinishedRedo 4 4
Object { key: 1, text: "hello", color: "green", location: "0 0", __gohashid: 725, loc: "19.5 13" }
Object { key: 2, text: "world", color: "red", location: "70 0", __gohashid: 726, loc: "91 13" }
Object { key: -3, text: "hello", color: "green", location: "0 0", __gohashid: 840, loc: "19.5 13" }
Object { key: -4, text: "world", color: "red", location: "70 0", __gohashid: 848, loc: "91 13" }

Hi @walter, sorry for the late reply.
I was able to narrow down the issue. The origin of the issue is not in the ChangeEvent listener.
The issue is that I am accessing the part.data in a node.selectionChanged handler, and the part.data is null during an undo operation. This causes the undo oepration to fail.

I did not expect the part.data to be null in the node.selectionChanged handler, so I am wondering if this is by design or if there is some other issue?

I have attached an example project, and here is a short gif:
undo

Example project: https://file.io/9FFHsloFTIJ3

When undoing the adding of a Part to the Diagram, the Part.selectionChanged event happens when the at-that-time-new Part had not yet gotten its data binding.

What do you mean by ‘at-that-time-new Part’? The undo operation removes the newly added node (Delta2 in the above example), and node “Delta2” seems to have a data binding?

Whatever the reason, if this is not something which should be changed in the goJS library, maybe its worth to add a note to the docs that the data might not be set? At least I didn’t know or find any information that the node.data might not be available in the selectionChanged handler.

The Part.data property might be null for other reasons. For example, unmodeled Parts never get any data because there is no data in the model for the Part.

okay, thank you!