Search code examples
javascriptjquerycytoscape.jscytoscape

Cytsocape.js can not create edge with nonexistant target


I try to create an edge after I created the nodes using an AJAX request.

My code:

success: function(data) {
    $.each(data['kids'], function(i, value) {
        cy.add({
            group: 'nodes',
            data: { id: value['id'] },
            position: value['position']
        });
    })
}

This works and created the nodes. Now, using this I try to create the edge:

cy.add({
    group: 'edges', data: { id: 'e0', source: 'n0', target: 'n1' }
});

but returns:

Can not create edge e0 with nonexistant source n0

Can not create edge e0 with nonexistant target n1

Below is my data result:

enter image description here

If I use this code, given as an example in documentation, everything works:

cy.add([
  { group: "nodes", data: { id: "n0" }, position: { x: 100, y: 100 } },
  { group: "nodes", data: { id: "n1" }, position: { x: 200, y: 200 } },
  { group: "edges", data: { id: "e0", source: "n0", target: "n1" } }
]);

What am I doing wrong?


Solution

  • Personally, I don't add the nodes and edges seperately, you could use an array to save the nodes and edges you want to add and then call cy.add():

    var array = [];
    // do your ajax calls
        success: function(data) {
            $.each(data['kids'], function(i, value) {
                array.push({
                    group: 'nodes',
                    data: { id: value['id'] },
                    position: value['position']
                });
            })
        }
    // add all edges
    array.push({
        group: 'edges', data: { id: 'e0', source: 'n0', target: 'n1' }
    });
    cy.add(array);
    

    Alternatively you could try to use cy.ready() to wait for the nodes to actually be added, otherwise it may occour, that the id's can't be found:

    cy.ready(function () {
         cy.add({
              group: 'edges', data: { id: 'e0', source: 'n0', target: 'n1' }
         });
    });
    

    Edit: Do you call the cy.add() for the edges in or outside of the ajax call? Ajax is a asyncrosous function call, so all the code after the call outside of the success function will probably be executed before you get to execute what you wrote in success. If you want you could wait for it to funish and put the second cy.add() for the edges in a promise handler like here:

    https://blog.revathskumar.com/2016/06/why-i-prefer-ajax-promise.html