Custom unique key function not always firing?

I’ve implemented a custom function that generates UUIDs instead of sequential values for view keys via:

diagram.model.makeUniqueKeyFunction = () => utilityService.newGuid();

I’m seeing odd behavior when dragging objects from my palette to the main canavs.

The first object dragged to the main canvas will have a view key of -1 in it’s nodeData.
The second object (of the same type) dragged onto the main canvas will have a view key of an expected UUID value.

I can reproduce this behavior consistently, however there are times (maybe 1 in 20 loads) where the custom key function seems to be ignored completely and objects dragged to the canvas all have default (sequential) view key values.

Ahh, yes. Because when you drag in the first node, its key won’t overlap, the function isn’t being called. Can you specify the function on the palette as well to ensure that node has a key that you want before dragging it? Another option would be not to copy the key during the copy.

I’m not sure about the consistency issue, are you seeing any errors and using go-debug.js?

Are you using the same makeUniqueKeyFunction in the Palette.model?

We are not currently using the makeUniqueKeyFunction in the palette. While that certainly seems like one potential solution, the mention of not copying the key during the copy seems interesting. Would that be part of the main canvas or the palette?

We have multiple palettes in our app, and it would be convenient for us not to have to repeat the same unique key function in all the various palettes.

You can set the copyNodeDataFunction on your diagram’s model. Something like in this small example, which generates odd numbered keys:

Thank you for that example - copyNodeDataFunction worked perfectly

facing same issue on unique key. everytime getting in negative numbers.

What are you using as the Model.copyNodeDataFunction?

same as the above codepan

When I run that codepen, I find that all of the new keys in the main diagram with the model that has that custom copyNodeDataFunction have positive odd numbers.

this.$(go.GraphLinksModel, { makeUniqueKeyFunction: this.keyGenerator, copyNodeDataFunction: function(data, model) { var newdata = Object.assign({}, data); newdata.key = self.keyGenerator; return newdata; } } );

You are assigning the node key value to be a function, which is neither a number nor a string.

so how it would be? I have a key generator method which returns 12 digits unique number, I tried to make only using makeUniqueKeyFunction which is set to key generator. in palete not given any key property.

Here’s a key generator for testing:

  function bigKeyGen(model, data) { 
    var k = Math.random().toFixed(18).substr(2);
    while (model.findNodeDataForKey(k)) k = Math.random().toFixed(18).substr(2);
    return k;
  }

Whenever you create a model, you need to make sure its Model.makeUniqueKeyFunction is set. This is taken from any of many samples:

  function load() {
    var str = document.getElementById("mySavedModel").value;
    myDiagram.model = go.Model.fromJson(str);
    myDiagram.model.makeUniqueKeyFunction = bigKeyGen;
  }

To make the palette’s data have unique keys:

    myPalette.model.makeUniqueKeyFunction = bigKeyGen;
    myPalette.model.nodeDataArray = [ . . . ];

I’m finding that as the user drags new nodes into the diagram from the palette, or just copies them within the main diagram, that each new node gets a key that was generated from bigKeyGen.

I think the main confusion comes from that key generator function not being called when there is an existing key on the node data being added and that key is already unique within the model. That behavior is required so that any references to existing keys aren’t lost.

yes when i removed existing nodedataarray json. then it is calling keygenerator, and works fine, but when existing key came in picture its lost.

When I run that codepen, I find that all of the new keys in the main diagram with the model that has that custom copyNodeDataFunction have positive odd numbers.

@walter The given codepen example function is not setting the first node dragged from the palette of each type to the desired positive key value. Did this functionality change or am I misunderstanding what you meant?

Setting the same makeUniqueKeyFunction on the palette breaks the sequential key generation, since it’s not using the same counter as the diagram.

Edit: Deleting the key property in the copyNodeDataFunction seems to force makeUniqueKeyFunction to fire, and you do not need to set anything special in the palette model.

copyNodeDataFunction: function(data, model) {
          var newdata = Object.assign({}, data);
          delete newdata.key;
          return newdata;
        },