Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot update node data after node is added to graph 'TypeError: Cannot assign to read only property' #2993

Closed
mkelly1495 opened this issue Mar 1, 2022 · 2 comments
Labels
bug A bug in the code of Cytoscape.js

Comments

@mkelly1495
Copy link
Contributor

Environment info

  • Cytoscape.js version : 3.21.0
  • Browser/Node.js & version : Chrome and Edge, Node: 14.19.0
  • Using in Angular 12.2.15

Current (buggy) behaviour
The documentation claims that I can update my custom properties for a given node using node.data(propName, propValue) or node.data({prop1:propVal1, prop2:propVal2}) after a node has been added to the graph. However, when I attempt this, I get TypeError: Cannot assign to read only property. All of my nodes are initialized with the desired properties when the graph is created. All I'm trying to do is update a property in the node data.

My code looks like this: myGraph.nodes().forEach(node => node.data('somePropery', 'someValue')). Cytoscape does not allow any properties in data to be changed. I understood that certain properties are immutable (e.g. id), but absolutely none of them are changeable. It doesn't matter what type the property is, I get the same behavior. I verified that Object.isFrozen(node.data()) is true which explains why nothing can be changed. I don't know what the magic is for updating an object, but I have tried everything I can think of and I can't find any answers online.

Desired behaviour
Node data is updateable as specified in the documentation.

Minimum steps to reproduce
Define a few classes:

export class NodeElementData {
  constructor(
    public id: string,
    public name: string,
    public altName: string) {}
}

export class CytoscapeNodeElement {
  constructor(
    public data: NodeElementData,
    public classes: string,
  ) {
  }
}

export class EdgeElementData {
  constructor(
    public id: string,
    public source: string,
    public target: string,
  ) {
  }
}

export class CytoscapeEdgeElement {
  constructor(
    public data: EdgeElementData,
    public classes: string = 'edge',
  ) {
  }
}

export class CytoscapeElements {
  constructor() {
    this.nodes = [];
    this.edges = [];
  }

  nodes: CytoscapeNodeElement[];
  edges: CytoscapeEdgeElement[];
}

Now create a new cytoscape graph:

let jsonVertexData = new CytoscapeElements();
jsonVertexData.nodes = new CytoscapeNodeElement(someNodeData, 'myClass');
jsonVertexData.edges = [];

let myGraph = cytoscape({
  container: document.getElementById('cy'), // container to render in
  elements: jsonVertexData,
  layout: dagreConfiguration,
});

Now attempt to update the altName property of a node:

myGraph.nodes().forEach(node => node.data('altName', 'SomeOtherName'));

For me this results in a TypeError: Cannot assign to read only property 'altName' of object '[object Object]'.

@mkelly1495 mkelly1495 added the bug A bug in the code of Cytoscape.js label Mar 1, 2022
@mkelly1495
Copy link
Contributor Author

OK - this appears to be my fault (big surprise). I am using NgRx for state management and it looks like NgRx is freezing the state objects prior to them getting into cytoscape.

@maxkfranz
Copy link
Member

maxkfranz commented Mar 2, 2022 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug in the code of Cytoscape.js
Projects
None yet
Development

No branches or pull requests

2 participants