Can you set model data property to the key of the created node?

For example, I have this nodedataarray for my palette:

palette.model.nodeDataArray = [
    { category: EquipmentNodeType.CAMERA, id: "0", nodeType: EquipmentNodeType.CAMERA, text: "Kamera" },
    { category: EquipmentNodeType.SIGN, id: "0", nodeType: EquipmentNodeType.SIGN, text: "Skilt" }
];

Is it possible for me to make the id get set to the key by default instead of “0” (essentially, can I grab the node that is being created here so I can access node.data.key)? I need the ID to get an initial unique value (will be mapped and overwritten later in the backend system).

My guess is that in both the Palette.model and the main Diagram.model you want to set Model.nodeKeyProperty to “id”. Then you do not need to set the id property in your palette’s node data Array.

All node keys would be automatically created and assigned to the id property. Your code could respond to a message from the server replacing the temporary key with the “real” identifier by calling Model.setKeyForNodeData, which would change the id property.

And maybe you want to set Model.nodeCategoryProperty to “nodeType”, if you mean for the nodeType to always be the same value as category.

No, this is just for when I create new nodes. Essentially ID is the unique identifier which my backend works with, while the key is the unique identifier for the diagram. The ID is included so that I can retrieve the correct object from backend while interacting with the diagram, so I do not want the ID property to be equal to the key under normal circumstances (the ID of different nodes could also be identical, but be different “equipmentnodetypes”, which would be problematic for the diagram if it was the same as the key).

The problem is on creation from palette since the ID isn’t unique at the moment of creation before it has interacted with the backend. If I drag in a new node and connect them to something, once the new nodes gets an ID in the backend, the connection object that has been created will point towards a nonexistant ID (since it’s now been changed from “0” to an actual ID, and the connection objects in backend points to id, not key). I will get around this by creating a map in my backing bean between keys and ID’s, then overwrite the connections I am going to create before I insert them into my backend db. But for this to work I will need the new nodes that are being created to get a unique ID when it’s created (as it is now, all new nodes are “0”).

So essentially, I just want the “id” property to obtain a unique string on creation, and I thought I might as well use the node key if possible since this is guaranteed to be unique.

OK, after the model has been assigned to the Palette, iterate through the nodeDataArray and copy the keys to the ids.

I’m not quite sure what you mean. The nodes in the palette itself has it’s own properties (it’s basically a node in a separate diagram) if I understand correctly. I don’t really care what the values are there. What I want is that when you drag from the palette and into the main diagram, the node that’s being generated in the main diagram needs to have it’s id set to it’s key. And I definitely don’t want existing nodes to have their actual ID overwritten with the key (only newly created nodes from palette).

…I suppose if there is an event that is raised on the creation of a node (from palette or otherwise, since I only create new nodes through the palette. As long as it doesn’t trigger when the diagram is initially loaded with myDiagram.model = …) I could overwrite the id with the key value at that point.

I have changed the title of this topic to reflect that you don’t want to change the palette data.

That is what the “ExternalObjectsDropped” DiagramEvent is for.

Thank you, that looks like something I could use. However, how do I access the data in this event? It says that e.subject should be the set of Parts that are being dropped: Part | GoJS API

A part doesn’t have direct access to the data, but it says it has key as a read-only field (which you could use with e.g. findNodeForKey). However, if I access e.subject.key in my event, it says the key is undefined. I suppose this is because it’s a “set” of parts, not just a part. But how do I obtain my node (or data, or top level part, so I can get the key to find the node/data) from this set?

Every Part does have direct access to its model data, via the data property.

e.subject.each(function(node) { node.data.id = ...; });

Oh… data property is part of the base class.

What you said does work. Thank you.

myDiagram.addDiagramListener("ExternalObjectsDropped", function(e) {
    e.subject.each(function(node) {
        var data = node.data;
        console.log("key: " + data.key);
        console.log("old id: " + data.id);
        data.id = data.key;
        console.log("new id: " + data.id);
    });
});

I was just worried that since it’s a “set” of parts doing this operation on the whole set may have unintended consequences. But it’s just being logged once per drop, so it seems to work fine. Sample output:

key: -1
old id: 0
new id: -1