Change not within a transaction: !d position: Link#129412

I have a code that align shapes (left / top …).

    alignLeft(actionNode: Node) {
        this.iterateAndCommitOverAllSelectedNodes((node: Node) => {
            let location = node.location.copy();
            location.x = actionNode.location.x - actionNode.width / 2 + node.width / 2;
            node.location = location;
        })
    }

    private iterateAndCommitOverAllSelectedNodes(callBack: (node: Node) => void) {
        let nodeArray = this.getAllSelectedNodesAsArray();
        if (nodeArray.length > 1) {
            this.diagram.commit(() => {
                nodeArray.forEach((node: Node) => callBack(node));
            });
        }

    }

    private getAllSelectedNodesAsArray() {
        let nodeArray = this.diagram.selection.toArray()
            .filter(part => part instanceof Node);
        return nodeArray;
    }

it works fine.
the problem I have is the I can see a message in the console.
Change not within a transaction: !d position: Link#129412(flow_0_4) old: Point(638.3500000000017,-332.5) new: Point(638.3500000000017,-340)

I have noticed that if I remove link.curve = go.Link.JumpOver then the problem goes away.

by looking at the stack trace I can see that gojs start a timer to change the points and this is why (I guess) I get this message.

what can I do to prevent this message?

Since it says “Change not within a transaction”, did you try changing the implementation of the alignLeft function to execute within a transaction. Whenever you make changes, particularly to a model, you should perform a transaction.

It’s common to call Diagram.commit or Model.commit.

Yes I did look at the code, it runs in a transaction.
alignLeft calls iterateAndCommitOverAllSelectedNodes , and pass a lamda function to a function that commits.

Odd, I did not see that call to commit before.

I’m not sure, but it appears that the link routing is not happening during the transaction. We’ll look into it.

location.x = actionNode.location.x - actionNode.width / 2 + node.width / 2;

Nodes don’t have .width properties, so this code seems odd. I would think you would want:

location.x = actionNode.location.x - actionNode.actualBounds.width / 2 + node.actualBounds.width / 2;

the Array.forEach is allowing frames to fire in between calls, and our general invalidation code is running. If you try just using a simple for-loop:

    private iterateAndCommitOverAllSelectedNodes(callBack: (node: Node) => void) {
        let nodeArray = this.getAllSelectedNodesAsArray();
        if (nodeArray.length > 1) {
            this.diagram.commit(() => {
                for (let i = 0; i < nodeArray.length; i++) {
                    callBack(nodeArray[i]);
                }
            });
        }
    }

Does it still happen? It doesn’t seem to, in my testing.

I do not know why Array.forEach seems to act as if it is non-blocking, I didn’t think it was. But that seems to be why.

It still happens.
note that it does not happen all the time

this is the stack trace

================================

================================

look below. when it does happen it call OO(this)

I guess this code start a timer

you can see in the stack trace that zone is activated.
this is angular catching async operations …

here is how it looks on the screen before left alignment

here is how it looks on the screen after alignment
image

note that if I remove the bottom left shape then the problem goes away

the problem exists also if I try this diagram and I align the “withRg…” to the left of “accountPerfmance”

It’s hard to know what’s doing this. We are expecting that requestAnimationFrame will not fire in the middle of synchronous code, and in my simplistic example it seems to work as I’d expect.

What is zone.js? It’s not clear to me what’s actually calling the task.

Broadly: In GoJS, if properties are modified, after a short while we update the Diagram. Properties are typically modified within a transaction, and the update at the end of a transaction removes the need for the timed update. But that is not happening here.

Angular zones are used by gojs-angular to improve performance by avoiding change detection during mouse-over events.

Angular

Sorry, this does seem to be a library issue, and we’re investigating a fix.

We have fixed this in 2.2, which will be out of beta soon. You can use npm i gojs@beta to start using it today.

this works for me!.
can you notify me when version 2.2 will be available?

Yes, I will notify you by email on release.

I installed the new version 2.2.0
but now I have another problem .
I can see the evaluation water mark.
image

how can I fix this?

New minor releases may require updating your Diagram.licenseKey. Request it at: Product Activation