Issues after upgrading GoJS from 2.3.5 to 3.x

Here is the full linkTemplate. I have a simple graph with only 3 nodes. There are 2 links connecting them together. The middle node is in a group. I don’t see any null links in the graph if that is what you are asking:

$(
      go.Link,
      {
        routing: go.Routing.AvoidsNodes,
        corner: 5,
        relinkableFrom: true,
        relinkableTo: true,
      },
      $(
        go.Shape,
        {
          name: 'linkLine',
        },
        new go.Binding('stroke', 'isHighlighted', function (h) {
          return h ? Colors.link.selected : Colors.link.default
        }).ofObject(),
        { strokeWidth: 3 },
      ),
      $(
        go.Shape,
        {
          name: 'linkArrow',
        },
        new go.Binding('stroke', 'isHighlighted', function (h) {
          return h ? Colors.link.selected : Colors.link.default
        }).ofObject(),
        new go.Binding('fill', 'isHighlighted', function (h) {
          return h ? Colors.link.selected : Colors.link.default
        }).ofObject(),
        { toArrow: 'Standard' },
      ),
    )

I notice your Group template doesn’t have a Node.location binding, which is useful for when the Group is collapsed, since then its Placeholder won’t be telling it where to be located.

But with or without such a binding, I cannot reproduce an exception. Here’s my code using your group template and link template. (I simplified the bindings involving your “Colors” class – that shouldn’t matter.)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8"/>
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, viewport-fit=cover"/>
  <meta name="description" content="Nodes with varying lists of ports on each of four sides."/> 
  <!-- Copyright 1998-2025 by Northwoods Software Corporation. -->
  <title>Simple AvoidsNodes Routing Test</title>
</head>

<body>
  <script src="https://cdn.jsdelivr.net/npm/gojs/release/go-debug.js"></script>

  <script id="code">
function init() {
  myDiagram =
    new go.Diagram("myDiagramDiv", { //Diagram refers to its DIV HTML element by id
        "animationManager.isEnabled": false,
        "undoManager.isEnabled": true
      });
  
  const $ = go.GraphObject.make;

  // the node template
  // includes a panel on each side with an itemArray of panels containing ports
  myDiagram.nodeTemplate =
    new go.Node("Table", {
        locationObjectName: "BODY",
        locationSpot: go.Spot.Center,
        selectionObjectName: "BODY"
      })
      .bindTwoWay("location", "loc", go.Point.parse, go.Point.stringifyFixed(1))
      .add(
        // the body
        new go.Panel("Auto", {
            row: 1, column: 1, name: "BODY",
            stretch: go.Stretch.Fill
          })
          .add(
            new go.Shape("Rectangle", {
                fill: "#dbf6cb", stroke: null, strokeWidth: 0,
                minSize: new go.Size(60, 60)
              }),
            new go.TextBlock({ margin: 10, textAlign: "center",
                font: "bold 14px Segoe UI,sans-serif", stroke: "#484848",
                editable: true
              })
              .bindTwoWay("text", "name")
          ),  // end Auto Panel body
      );  // end Node

  // an orthogonal link template, reshapable and relinkable
  myDiagram.linkTemplate =
    $(go.Link, {
        routing: go.Routing.AvoidsNodes,
        corner: 5,
        relinkableFrom: true,
        relinkableTo: true,
      },
      $(go.Shape, {
          name: 'linkLine',
        },
        new go.Binding('stroke', 'isHighlighted', function (h) {
          return h ? "dodgerblue" : "black"
        }).ofObject(),
        { strokeWidth: 3 },
      ),
      $(go.Shape, {
          name: 'linkArrow',
        },
        new go.Binding('stroke', 'isHighlighted', function (h) {
          return h ? "dodgerblue" : "black"
        }).ofObject(),
        new go.Binding('fill', 'isHighlighted', function (h) {
          return h ? "dodgerblue" : "black"
        }).ofObject(),
        { toArrow: 'Standard' },
      ),
    );
  
  myDiagram.groupTemplate =
    $(go.Group, 'Auto', {
        isSubGraphExpanded: false,
      },
      new go.Binding('location', 'loc', go.Point.parse, go.Point.stringify),
      new go.Binding('background', 'isHighlighted', function (h) {
        return h ? '#dedede' : 'transparent'
      }).ofObject(),
      $(go.Shape, 'Rectangle', { fill: null, stroke: "blue", strokeWidth: 2 }),
      $(go.Panel, 'Vertical', // title above Placeholder
        $(go.Panel, 'Horizontal', // button next to TextBlock
          { stretch: go.GraphObject.Horizontal, background: "lavender" },
          $('SubGraphExpanderButton', { alignment: go.Spot.Right, margin: 5 }),
          $(go.TextBlock, {
              alignment: go.Spot.Left,
              editable: true,
              margin: new go.Margin(5, 15, 5, 5),
              font: 'bold 14px roboto, normal',
              //opacity:0.75,
              stroke: '#ffffff',
            },
            new go.Binding('text', 'label').makeTwoWay(),
          ),
        ), // end Horizontal Panel
        $(go.Placeholder, { padding: 5, alignment: go.Spot.TopLeft }),
      ) // end Vertical Panel
    ); // end Group and call to add to template Map

    // load the diagram from JSON data
  load();
}


// Save the model to / load it from JSON text shown on the page itself, not in a database.
function save() {
  document.getElementById("mySavedModel").value = myDiagram.model.toJson();
  myDiagram.isModified = false;
}
function load() {
  myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
}
window.addEventListener('DOMContentLoaded', init);
  </script>

  <div id="myDiagramDiv" style="width:600px; height:500px; border:1px solid black"></div>
  <div>
    <div>
      <button id="SaveButton" onclick="save()">Save</button>
      <button onclick="load()">Load</button>
      Diagram Model saved in JSON format:
    </div>

    <textarea id="mySavedModel" style="width:100%;height:250px">
{ "class": "GraphLinksModel",
  "copiesArrays": true,
  "copiesArrayObjects": true,
  "pointsDigits": 1,
  "linkFromPortIdProperty": "fromPort",
  "linkToPortIdProperty": "toPort",
  "nodeDataArray": [
{"key":1,"name":"Unit One","loc":"88.3 207.2"},
{"key":2,"name":"Unit Two","loc":"395.9 189.3"},
{"key":3,"name":"Unit Three","loc":"227.8 198.9","group":5},
{"key":5,"isGroup":true,"name":"a Group","loc":"178.18158035278321 163.9","isSubGraphExpanded":false}
],
  "linkDataArray": [
{"from":1,"to":2,"fromPort":"right0","toPort":"left1"},
{"from":1,"to":2,"fromPort":"right1","toPort":"left2"}
]}
    </textarea>
  </div>
</body>
</html>

Oh, the “$” isn’t jQuery – it’s a GraphObject.make abbreviation.

… continued in Error with groups in Go.js 3.x

A post was merged into an existing topic: Need more insight on a11y / accessibility