Relinking is not working

Hi,

The following is an excerpt from our project:

<html>
<head>
    <title></title>
    <meta charset="UTF-8">
    <script src="go.js"></script>
    <script>
        var styling = {
            node: {
                strokeWidth: 2,
                selectionStrokeWidth: 4
            },
            link: {
                strokeWidth: 2
            }
        };
        var g = go.GraphObject.make;

        function createNodeTemplateMap() {
            var map = new go.Map('string', go.Node);
            map.add('BaseShape', createRoundRectNode(70, 70, 130, 100));
            return map;
        }

        function createLinkTemplateMap() {
            var map = new go.Map('string', go.Link);
            map.add('', createDefaultLink());
            return map;
        }

        function createPort(overrideOptions) {
            var options = {
                width: 7, height: 7,
                fill: 'transparent',
                stroke: 'transparent',
                toLinkable: true,
                fromLinkable: true,
                toMaxLinks: 99,
            };

            options.toSpot = overrideOptions.toSpot;
            options.fromSpot = overrideOptions.fromSpot;
            options.portId = overrideOptions.portId;
            options.alignment = overrideOptions.alignment;
            options.name = overrideOptions.name;

            return g(go.Shape, 'Rectangle', options);
        }

        function createNodePorts(top, right, bottom, left) {
            return [
                createPort({
                    alignment: new go.Spot(0.5, 0 + top),
                    portId: 'T',
                    fromSpot: go.Spot.Top,
                    toSpot: go.Spot.Top,
                    name: 'PortT'
                }),
                createPort({
                    alignment: new go.Spot(0 + left, 0.5),
                    portId: 'R',
                    fromSpot: go.Spot.Left,
                    toSpot: go.Spot.Left,
                    name: 'PortR'
                }),
                createPort({
                    alignment: new go.Spot(0.5, 1 - bottom),
                    portId: 'B',
                    fromSpot: go.Spot.Bottom,
                    toSpot: go.Spot.Bottom,
                    name: 'PortB'
                }),
                createPort({
                    alignment: new go.Spot(1 - right, 0.5),
                    portId: 'L',
                    fromSpot: go.Spot.Right,
                    toSpot: go.Spot.Right,
                    name: 'PortL'
                })
            ];
        }

        function createEventOptions() {
            return {
                mouseEnter: function (e, obj) {
                    togglePortsVisibility(obj, true);
                },
                mouseLeave: function (e, obj) {
                    togglePortsVisibility(obj, false);
                }
            };
        }

        function togglePortsVisibility(obj, show) {
            var portNames = ['PortL', 'PortR', 'PortT', 'PortB'];

            portNames.forEach(function (portName) {
                var port = obj.findObject(portName);
                if (port) {
                    port.fill = show ? 'white' : 'transparent';
                    port.stroke = show ? 'black' : 'transparent';
                }
            });
        }

        function createRoundRectNode(imageWidth, imageHeight, shapeWidth, shapeHeight) {
            return g(go.Node, 'Auto',
                    createEventOptions(),
                    g(go.Shape, 'RoundedRectangle', {
                                width: shapeWidth || 110,
                                height: shapeHeight || 90,
                                fill: '#f2f2f2',
                                stroke: '#cdcdcd',
                                strokeWidth: styling.node.strokeWidth
                            },
                            new go.Binding('stroke', 'isSelected', function (b) {
                                return b ? '#16c4d9' : '#cdcdcd';
                            }).ofObject()),
                    g(go.TextBlock,
                            {
                                wrap: go.TextBlock.WrapFit,
                                textAlign: 'center',
                                editable: true,
                                font: '12px sans-serif, Helvetica, Arial',
                                alignment: new go.Spot(0.5, 0.8),
                            }, new go.Binding('text', 'text')),
                    g(go.Picture, {
                        width: imageWidth,
                        height: imageHeight,
                        alignment: new go.Spot(0.5, 0.1)
                    }, new go.Binding('source', 'image')),
                    new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
                    createNodePorts(0, 0, 0, 0)
            );
        }


        function createDefaultLink() {
            return g(go.Link, {
                        routing: go.Link.AvoidsNodes,
                        curve: go.Link.JumpOver,
                        corner: 3,
                        relinkableFrom: true,
                        relinkableTo: true,
                        selectionAdorned: false
                    },
                    g(go.Shape, {strokeWidth: styling.link.strokeWidth, stroke: '#989898'}),
                    g(go.Shape, {toArrow: "Triangle", stroke: '#989898', strokeWidth: 1, fill: '#989898'}));
        }

        function init() {
            var diagram = g(go.Diagram, 'myDiagram', {
                initialContentAlignment: go.Spot.Center,
                'undoManager.isEnabled': true,
                allowDrop: true
            });

            diagram.nodeTemplateMap = createNodeTemplateMap();
            diagram.linkTemplateMap = createLinkTemplateMap();

            diagram.model = go.Model.fromJSON({
                'nodeDataArray': [
                    {key: 1, text: 'A', category: 'BaseShape', loc: '300,520'},
                    {key: 2, text: 'B', category: 'BaseShape', loc: '-100, 0'},
                    {key: 3, text: 'C', category: 'BaseShape', loc: '100,100'}],
                'linkDataArray': [{from: 1, to: 2}]
            });
        }
    </script>

</head>
<body onload="init()">
    <span style="display: inline-block; vertical-align: top; padding: 5px; width:80%">
      <div id="myDiagram" style="border: solid 1px gray; height: 620px"></div>
    </span>
</div>
</body>
</html>

When trying to move one of the link’s end/start and reconnect it to the unconnected shape, it does not let me do so.
What am I doing wrong here ?

Thanks,
Oren

Found the problem, missed :

portId: "", 
fromLinkable: true,
toLinkable: true 

on the shape I main shape.

Another problem is that you do not turn on support for separate ports in the GraphLinksModel. You need to specify the property names used for port identifiers in the link data by setting GraphLinksModel.linkToPortIdProperty and GraphLinksModel.linkFromPortIdProperty. Note how sample apps such as Flow Chart or Dynamic Ports set those properties in the model.