Skip to content

initializeModel strips targetPosition/sourcePosition, breaking dangling edges loaded from a model #751

Description

@Mateusz-Jagodzinski

What happens

A "dangling" edge — one end is a node/port, the other is a free point defined only by targetPosition (target: '') — works when added at runtime via addEdges, but when the same edge is seeded through initializeModel, its targetPosition is discarded. The edge then has no resolvable endpoint, so ng-diagram logs Invalid edge coordinates detected on every routing pass and the edge can't be routed.

Repro: StackBlitz

Both edges are dangling and identical except that, after initializeModel, restored re-applies its targetPosition via model.updateEdges while broken does not.

  1. Open the console on load → one error: Invalid edge coordinates detected for edge 'broken'. broken renders nothing; restored renders fine.
  2. Drag the Source node → broken re-logs the error on each routing pass; restored follows the node and stays silent.

The post-init updateEdges call is the only difference, which isolates the cause.

Cause

initialize-model.ts#L100 runs every edge through stripEdgeRuntimeProperties, defined at strip-runtime-properties.ts#L27-L33, which removes sourcePosition and targetPosition (along with measuredLabels, computedZIndex, _internalId).

For a connected edge this is harmless — routing recomputes the endpoints from the measured ports. But for a dangling edge, targetPosition/sourcePosition is the only source of truth for the free end, so stripping it removes authored data. Note the asymmetry: addEdges/updateEdges don't strip, which is why runtime-created dangling edges work.

What I'd like

Stripping computed values on init is reasonable in general (the doc comment is right — stale measuredLabels/computedZIndex from a persisted model should be dropped). But it shouldn't throw away the authored free-end position of a dangling edge. I'd like some supported way to define/persist a model that contains dangling edges, so they survive toJSONinitializeModel (which currently both strip) and can be reloaded.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions