We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date

Random Bug with connector with "diagram.remove()", Angular7+, TypeScript 3+

Hi,

I have a diagram that, when a user does not connect a connector to another node, it has to delete itself. It worked fine in the beginning, but now the diagrams gets more complicated(more nodes and connectors) it shows a weird bug sometimes.
When the diagram is filled with 10+ connectors(&diagrams) and the code tries to delete the selected unconnected connector with no targetID, it sometimes returns an error. 
But it doesnt make any sense, why? It works fine sometimes and sometimes it doesn't. The diagram can't seem to find the connector it's trying to delete??
I have added a zip with a GIF for a visual example. In the example it works and then the second time it freezes with an error. 

Tried:
- I have "loaded" a diagram into the diagram directly, with 25+ connectors and 25+ nodes and it random happens when the user does not "finish" a connection.
- I have started from scratch connecting different nodes and suddenly it just happens when a user doesnt "finish" a connection.

Info:
The connector cannot be manually adjusted when a connection is created between nodes(Readonly).
The connector needs to be automatically deleted if there is no target when the user does not finish the connection after dragging.

////////////////////////////////////////////////////////////////////////////////////////////////////////////

THE CODE:
  //set the properties of the connector
  getConnectorDefaults(args: ConnectorModel, diagram: Diagram): ConnectorModel {
    args.targetDecorator.height = 5;
    args.targetDecorator.width = 5;
    args.style.strokeColor = "#797979";
    args.targetDecorator.style = { fill: "#797979", strokeColor: "#797979" };
    args.constraints = ConnectorConstraints.Default | ConnectorConstraints.ReadOnly; // User cannot adjust connector afterwards, only delete
    return args;
  };


  //prevent userhandles from showing on connector
  selectionChange(args: ISelectionChangeEventArgs) {
    if (args.state === "Changed" && args.newValue[0] instanceof Connector) {
      if ((args.newValue[0] as any).targetID === "") {
      console.log(args) //<--the connector still exists
      this.diagram.remove(args.newValue[0]);  ERROR ->  this is row 413, see below)
      }
    } else {
    if (args.state === "Changing" && args.type === "Addition" && args.newValue[0]) {
        if (args.newValue[0] instanceof Connector) { //Block handles form view on connector
          this.diagram.selectedItems.userHandles[0].visible = false; // is copy handle
          this.diagram.selectedItems.userHandles[1].visible = false; // is drawing handle
        } else {
          this.diagram.selectedItems.userHandles[0].visible = true;
          this.diagram.selectedItems.userHandles[1].visible = true;
        }
      }   
    }
  }

//Defines the link tool used to link Connector
class MyLinkTool extends ConnectorDrawingTool {
  diagram: DiagramComponent = null;
  mouseDown(args: MouseEventArgs): void {
    var connector: ConnectorModel = {
      type: "Straight",       // initialize the straight line connector  
      sourceID: this.diagram.selectedItems.nodes[0].id      // Source node id have been set  
    };
    // sets the straight line connector as the drawing object. 
    this.diagram.drawingObject = connector;
    super.mouseDown(args);
    this.inAction = true;
  }
}

  //prevent user from dragging connector
  connectionChange(args: IConnectionChangeEventArgs) {
    console.log(args);
    if (args["state"] === "Changing" && args.connector) {
      args.cancel = true;
    }
  }


THE ERROR:
ERROR TypeError: Cannot read property 'length' of undefined
    at DiagramComponent.push../node_modules/@syncfusion/ej2-diagrams/src/diagram/diagram.js.Diagram.spliceConnectorEdges (diagram.js:1355)
    at DiagramComponent.push../node_modules/@syncfusion/ej2-diagrams/src/diagram/diagram.js.Diagram.remove (diagram.js:1496)
    at FlowComponent.push../src/app/flow/flow.component.ts.FlowComponent.selectionChange (flow.component.ts:413) 
    at Object.eval [as handleEvent] (FlowComponent.html:58)
    at handleEvent (core.js:19628)
    at callWithDebugContext (core.js:20722)
    at Object.debugHandleEvent [as handleEvent] (core.js:20425)
    at dispatchEvent (core.js:17077)
    at core.js:18567
    at SafeSubscriber.schedulerFn [as _next] (core.js:10250)

package.json:
  "@syncfusion/ej2-angular-base": "^16.3.32",
    "@syncfusion/ej2-angular-buttons": "^16.3.30",
    "@syncfusion/ej2-angular-diagrams": "^16.3.30",
    "@syncfusion/ej2-angular-grids": "^16.3.30",
    "@syncfusion/ej2-angular-inputs": "^16.3.30",
    "@syncfusion/ej2-angular-lists": "^16.3.30",
    "@syncfusion/ej2-angular-navigations": "^16.3.30",
    "@syncfusion/ej2-angular-splitbuttons": "^16.3.30",



Attachment: error_c7c248d6.zip

4 Replies

RT Ramya Thirugnanam Syncfusion Team November 26, 2018 12:07 PM UTC

Hi Laurens, 
 
Reported issue : Cannot read property 'length' of undefined when remove the connector. 
 
We have validated the provided code examples and we were unable to replicate the reported issue.  
 
Could you please let us know whether inedges or outedges of the node is set null in your application? This will help us to serve you better. 
 
 
Regards, 
Ramya T 



LA Laurens Albers November 26, 2018 12:47 PM UTC

Hi, 

The result:
  selectionChange(args: ISelectionChangeEventArgs) {
    if (args.state === "Changed" && args.newValue[0] instanceof Connector) {
      if ((args.newValue[0] as any).targetID === "") {
      console.log(this.diagram.nodes)               //<-- data below is generated using the following line and looking up the node with those "connectors"
      this.diagram.remove(args.newValue[0]);  //ERROR Location
      }
    } else {

added image as zip as example:
id"sort2ovt3" //id of the node
inEdges(7) ["EG1JH""siR5X""NbROJ""f0ZoS""ORhNA""toePG""MZJ0o"] //this is correct
outEdges(9) ["G2TTf""T9JEh""NvDTn""ZE2Id""bxcor""ucWkM""u0V0N""bSHSp""L38BJ"] // this is incorrect, it's missing the one that just finished "drawing" and should be deleted

In the image you can visually see 7 inputs, and 9 +1(10) outputs, the +1 being the one that has finished being drawn, pointing downwards.

Attachment: Knipsel_3a9a66a7.zip


LA Laurens Albers November 26, 2018 01:41 PM UTC

Discovered the following:
//Defines the link tool used to link Connector
class MyLinkTool extends ConnectorDrawingTool {
  diagram: DiagramComponent = null;
  mouseDown(args: MouseEventArgs): void {
    console.log(this.diagram.selectedItems.nodes[0].id) // Let say the id here is id:12345
    var connector: ConnectorModel = {
      // initialize the straight line connector  
      type: "Straight",
      // Source node id have been set
      sourceID: this.diagram.selectedItems.nodes[0].id // the sourceID(12345) is being set
    };
    // sets the straight line connector as the drawing object. 
    this.diagram.drawingObject = connector;
    super.mouseDown(args);
    this.inAction = true;
  }
}

//Let say i do the exactly same action drag and drop(unfinished) about a random amount of  times, at some point it does this following.
 selectionChange(args: ISelectionChangeEventArgs) {
    if (args.state === "Changed" && args.newValue[0] instanceof Connector) {
      if ((args.newValue[0] as any).targetID === "") {
        console.log(args.newValue[0].sourceID)  // the id has changed(example 12345 is now 67890) ???Huh????
           this.diagram.remove(args['element']);
      }

I think just after setting the ID is the location of the bug. If I keep repeating this, it will change the ID of the source at some point. very weird.



KR Karkuvel Rajan Shanmugavel Syncfusion Team November 27, 2018 10:52 AM UTC

Hi Laurens,   
We have created a sample from your code examples. We were unable to replicate the issue. From the given stack trace we have identified that in spliceConnectorEdges if the node inEdges or outEdges value sets to null or undefined the issue occurs. But in our source we have checked that we does not set undefined to the node inEdges or outEdges we just set an empty array collection to the edges.    
  
We have shared a sample and please confirm us whether we applied all your code settings or not. Please find the sample in below link   
  
  
Regards   
Karkuvel Rajan S   


Loader.
Live Chat Icon For mobile
Up arrow icon