Refreshing diagram after Restful HTTP post in a context menu

I have a context menu for nodes and subscribe to an http post call in one of the menu buttons. It is set up to have a server remove an item from the database from which the diagram is built. Unfortunately, the diagram elements are not visible inside the response region of my rest call; this means I’m having difficulty removing the nodes from the diagram displayed to reflect the changes that were made on the back end. I am positive the database transaction is successfully deleting the correct item, though I’d like to update the graph in my UI to reflect the change.

Any suggestions?

When the XMLHttpRequest succeeds, do you get back the identifier or key of the item(s) that were deleted? If so, at that time you can perform a transaction to remove those objects from the model.

I already know what node I want removed from the diagram anyways, while having to send that data back from the server seems like a waste when it’s a scope issue.

I’m looking into using an event or diagram listener to react to the context menu’s button being clicked, in case that would still have access to the objects I need.

If you know which node(s) to delete at the time the context menu button’s click event handler issues its XMLHttpRequest, then optimistically you can go ahead and delete it. Just call Diagram.removeParts within a transaction.

I may be using the calls incorrectly, but it still doesn’t seem to be updating the diagram.

I’ve tried a few different things so far:

//////////////////////
myDiagram.commit(function(e) {
myDiagram.removeParts([part], false);
});
//////////////////////
myDiagram.startTransaction(“DeleteEntity”);
myDiagram.removeParts([part], false);
myDiagram.commitTransaction(“DeleteEntity”);

Those two bits of code are effectively the same, except for giving the transaction a human-readable name (“DeleteEntity”).

Are you sure that you are passing the right part to the call to removeParts? How do you find it?

I have a context menu set up to appear when I right click on a node, which then lets me access an object from the inner click function. I am able to see the exact part name from obj.part.data.tagName, so I’m actually using a print statement to confirm the part data:

console.log(obj.part.data.tagName);

rest.post(‘http://…’, data).subscribe(res => {
myDiagram.commit(function(e) {
myDiagram.removeParts([obj.part], false);
});
}

I’m not sure if I have to remove the links and any child node from the graph as well, but any suggestions are worth a try at this point.

So you want to delete the node on which the context menu appeared? I had thought you meant to remove some other node.

The call to Diagram.removeParts should remove any relationships with the removed part(s) as well as any parts that they “own”. I think the documentation says as much: https://gojs.net/latest/api/symbols/Diagram.html#removeParts

That’s what I was leaning towards, but the problem remains that it isn’t deleting the node nor the children.

I just tried a simple case of having a context menu button delete the node it was invoked on by calling Diagram.removeParts:

      $(go.Node, "Auto",
        { width: 100, height: 50 },
        {
          contextMenu:
            $("ContextMenu",
              $("ContextMenuButton",
                $(go.TextBlock, "Delete Me After 2 Seconds"),
                {
                  click: function(e, button) {
                    var node = button.part.adornedPart;
                    setTimeout(function() {
                      node.diagram.commit(function(diag) {
                        diag.removeParts([node], false);
                      })
                    }, 2000);
                  }
                }
              ))
        },
        $(go.Shape,
          { fill: "white", portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer" },
          new go.Binding("fill", "color")),
        $(go.TextBlock,
          { margin: 8, editable: true },
          new go.Binding("text").makeTwoWay())
      );

It worked well for me.

Unfortunately, my button doesn’t show any adornedPart element, so I can’t do this.
Specifically, “Property ‘adornedPart’ does not exist on type ‘Part’.” :(

I guess you are not using GoJS context menus. Still, you must have some way of knowing which node the context menu command should be working on.

It’s definitely a GoJS context menu; the only difference I see is that mine is defined within the init function that encapsulates the diagram code, rather than writing all the code locally inside the node.template definition. I’d be surprised if that is making that much of a difference.

Well, it’s hard for anyone to give you advice unless you show the relevant code (and only the relevant code).

Here is the definition of the context menu, including where I log the part to make sure it’s seeing the correct one, through to the commit:

// Drop down menu when right clicking on a node.
    let restful = this.http;
    let rightClickMenu = $("ContextMenu",
      $("ContextMenuButton",
        // First option.
        $(go.TextBlock, "Delete Node"),
        { click: function(e, obj)
          { console.log("PRESSED DELETE");
            console.log(obj.part.adornedPart);
            let adorned = obj.part.adornedPart;
            console.log("DATA:");
            console.log(obj.part.data);
            console.log("TAG:");
            console.log(obj.part.data.tagName);
            if (obj.part.data.tagName !== null) {
                restful.post('http://localhost:8080/doc/del', obj.part.data.tagName).subscribe(result => {
                  if (result.status === 200) {
                    console.log("SUCCESSFUL DELETE");
                    
                    //myDiagram.commit(function(c) {
                    adorned.diagram.commit(function(d){
                      d.removeParts([adorned], false);
                      console.log("Commiting the removal.");
                    });

Please format your code so that it is readable, by surrounding it with lines of triple backquotes. I’ve just done this for you.

What do you do with rightClickMenu?

Then I make the rightClickMenu the context menu for the node (I’ve also tried specifying individual sections of nodes their own menu, which does show it when clicking on specific parts) in the node template.

Here’s one of the spots I’ve used the menu within the node template:

$(
          go.TextBlock,
          {
            contextMenu: rightClickMenu,
            row: 1,
            column: 0,
            columnSpan: 2,
            font: '12px Roboto, sans-serif',
            alignment: go.Spot.Left
          },
          new go.Binding(...)
        ),

And all of the console.log statements execute as you would expect? But the deletion does not happen? That’s odd.