Search code examples
javascriptsveltesveltekitgojs

GoJS `diagram.model.toJson()` is not not updating after change


I am using SvelteKit and GoJS

I've declared let diagram; before onMount(), and defined diagram = new go.Diagram('Diagram'); inside onMount() and all other details after that, including:

diagram.addModelChangedListener((e) => {
            if (e.isTransactionFinished) {
                saveDiagramToLocalStorage(); 
            }
});

saveDiagramToLocalStorage(); is defined after onMount():

const saveDiagramToLocalStorage = () => {
        const modelAsJson = diagram.model.toJson();
        console.log('SaveDiagram', modelAsJson);    // no changes on current data
        localStorage.setItem('myDiagramModel', modelAsJson);
};

And its all working fine, the function saveDiagramToLocalStorage() is beeing called, but,

The issue is:

diagram.model.toJson(); is always returning the same data, in other words is not being updated after changes in diagram.

Except:

Adding new node or link. The new ones are added, but the existing ones are still not updated. (I'm calling diagram.selection.<some_data> and that's well updated, but the diagram.model.toJson() is not picking changes on the existing ones for some reason)

I've tried:

  • putting Diagram.rebuildParts() before diagram.model.toJson();
  • putting saveDiagramToLocalStorage() inside onMount

Solution

  • It was a binding issue

    Do not use this for binding:

    .bind('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify)
    

    Always use go.GraphObject.make and makeTwoWay in your diagram.nodeTemplate to keep diagram.model fully updated with this kind of binding:

    new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify)
    

    Full context: (working example)

    // +page.svelte / <script>
    onMount(() => {
        const $ = go.GraphObject.make;
        diagram = $(go.Diagram, DiagramDiv);
    
        diagram.nodeTemplate = $(
            go.Node,
            'Auto',
            {
                width: 50,
                height: 50
            },
            new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify)
        )
    });