Does mergeNodeDataArray uses a shallow compare?

I was investigating for a while why gojs-react returns all my blocs in modifiedNodeData, I found out later that after reinsializing my state, mergeNodeDataArray will consider any new object reference as a recent change.

This object data { key: 0, name: 'Test' }

Does not behave the same as { key: 0, name: 'Test', things: {} }

Demo here, click on the button to see the difference

The way I am using right now is to stringify all the object and parse them later in the bindings

However I think this will affect the performance.

I am not sure how can I pass objects within objects in gojs without triggering onModelChange twice.

Any idea about this issue ?

It doesn’t compare objects at all. For each given key value in the argument Array’s node data objects, it finds the corresponding node data object in the Model. It then calls Model.assignAllDataProperties, which basically just calls Model.setDataProperty for each of the enumerable properties on the given data.

I see that setDataProperty is smart enough to detect if a string, boolean, null, undefined or number were really changed but it does’t behave the same for objects and arrays.

Because javascript consider {} === {} as falsy ? Same for [] === [] ?

Try this snippet

const setDataProperty = () => {
    const node = diagram.current.model.findNodeDataForKey(0);
    diagram.current.model.startTransaction("Do stuff");
    diagram.current.model.setDataProperty(node, "data", '');
    diagram.current.model.commitTransaction("Done");
  };

Execute this multiple times and notice that onModelChange is called only when the data receive a new value. Setting the same value will not trigger onModalChange.

Now try the same code with setDataProperty(node, “data”, {}) or setDataProperty(node, “data”, []). Despite it’s the same value the event listner will consider it as a real change (shallow compare ?) and force gojs to update.

Maybe you are using this by default since deep compare is heavier, however is there any possible way to provide a custom compare function to prevent triggering the model change events when there is no real changes ?

Another Codesanbox example

Yes, because {} !== {} and because [] !== [].

You might want to read: GoJS Using Models -- Northwoods Software

Perfect. Thank you !