copyNodeDataFunction is called twice

I’m trying to have a unique name for my nodes when they are copied and pasted. So I add a _1 to the name property in the copyNodeDataFunction like this:

copyNodeDataFunction: (data, model) => {
  let newData = deepCopy(data);
  newData.name = data.name + "_1";
  return newData;
}

But this function is called twice: once on ctrl-c and once on ctrl-v and the final node comes out with double _1_1 appended to the name. What am I doing wrong?

Ctrl-C calls CommandHandler.copySelection which makes a copy of the selected parts to save in the clipboard.

Then Ctrl-V calls CommandHandler.pasteSelection which makes a copy of the data/parts in the clipboard.

So it makes sense that each node data object gets copied twice. Maybe you want to add that suffix only when the model is the Diagram.model.

when the model is the Diagram.model

Can you elaborate on this? This is GraphLinkModel and all I want is to add that suffix when a node is copy/pasted.

I’m suggesting that you only do it when pasted, which you can check by comparing the model argument with the Diagram.model.

I’ll be honest with you, I have zero idea what you’re talking about. The diagram.model is exactly the same as the model passed into this function. Same number of nodes and same data.

After the paste is done and this function is run only then I have the new node added.

Sorry, I was confusing this with another similar situation.

The problem is that the node-data-copying-functionality doesn’t by itself know why the copy is being made. I’ll continue to assume you only want to add that name suffix when a paste happens, not when a copy happens.

One way to provide that information is to override CommandHandler.pasteFromClipboard so as to pass the information that that method is being called to your copyNodeDataFunction. For example you could set a global variable.

Alternatively you could look to see whether there is a transaction ongoing. If there isn’t, it’s most likely a copy (i.e. CommandHandler.copySelection). Something like:

copyNodeDataFunction: (data, model) => {
  let newData = deepCopy(data);
  if (model.undoManager.isInTransaction) {
    newData.name = data.name + "_1";
  }
  return newData;
}

However, that won’t distinguish a clipboard “paste” from a drag “copy”. I don’t know if that matters to you.

Awesome, that’s exactly what I wanted. Even the drag copy is desired. Thanks very much.