Skip to content

fix(cases): break the EformCasesModule import cycle in case-edit components - #8159

Merged
renemadsen merged 1 commit into
angular19from
ng21/cases-cycle
Oct 18, 2026
Merged

renemadsen merged 1 commit into
angular19from
ng21/cases-cycle

Conversation

@renemadsen

Copy link
Copy Markdown
Member

Problem

While debugging the backendconfiguration Playwright tests, the browser logged NG0919 ("Cannot read @directive metadata ... runtime circular dependency"). app-case-edit-element never rendered inside the case-complete modal.

Cause

  • CaseEditElementComponent and CaseEditNavComponent had EformCasesModule in their standalone imports, and EformCasesModule imports and exports those same components. In the built chunk the module is defined after the components, so their eager dependencies arrays held undefined.
  • CaseEditSwitchComponent and ElementContainerComponent import each other directly. The bundle defined the switch first (ue at offset 21921), and its dependencies:[…,kt,…] referenced the container (kt), which wasn't assigned until offset 23102. So nested element-containers were dropped as well.

A scan of every component, directive and pipe under src/app for imports of a local NgModule that refers back to the importing class found only these two module cycles.

Fix

  • Removed EformCasesModule from both components. They only used it to render themselves recursively, and a standalone component can already use its own selector, so nothing replaces it.
  • CaseEditSwitchComponent and ElementContainerComponent now import each other through forwardRef(() => …). The compiler then emits dependencies: () => [...], which is resolved lazily and works whichever order the bundler picks.

Verification

  • npx ng build: bundle generated, no errors. Only the existing NG8113 warnings remain, none of them in the touched components.
  • Built output: app-case-edit-element → dependencies:[t,…] (itself plus concrete imports, no module); app-case-edit-nav → [t,NgFor,NgIf]; switch and container → dependencies:()=>[…].
  • npx ng test --watch=false: 3535 passed, 9 skipped. The only failures (3) are in time-planning-pn/help/playwright-tour-seed.spec.ts, from a locally synced, untracked plugin folder that isn't part of this repo, and they have nothing to do with this change.

🤖 Generated with Claude Code

…onents

CaseEditElementComponent and CaseEditNavComponent listed EformCasesModule
in their standalone `imports`, while EformCasesModule imports and exports
those same components. In the production bundle the module class is
defined after the components, so their eager `dependencies` arrays held
`undefined`. At runtime Angular threw NG0919 ("Cannot read @directive
metadata ... runtime circular dependency") and app-case-edit-element never
rendered, e.g. in the case-complete modal.

Both components only needed the module to render themselves recursively.
A standalone component can already use its own selector, so the module
import is removed and nothing replaces it.

CaseEditSwitchComponent <-> ElementContainerComponent is a direct cycle
of the same kind: the bundle defined the switch before the container, so
the switch's dependency list captured `undefined` for element-container.
Both sides now import each other through forwardRef, so the compiler
emits a lazy `dependencies: () => [...]` closure that works whichever
order the bundler picks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copilot AI balanced review requested due to automatic review settings October 18, 2026 14:14

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused dependency changes preserve recursive rendering, and no blocking issues were identified.

No open issues 🎉

What changed in this PR

Fixes circular Angular dependencies that prevented case-edit components from rendering in the case-complete modal.

Changes:

  • Removes unnecessary EformCasesModule imports from recursive standalone components.
  • Uses forwardRef for the mutual switch/container dependency.
File Description
eform-client/​src/​app/​common/​modules/​eform-cases/​components/​case-edit/​case-elements/​element-container/​element-container.component.ts Defers the switch component dependency.
eform-client/​src/​app/​common/​modules/​eform-cases/​components/​case-edit/​case-edit-switch/​case-edit-switch.component.ts Defers the container component dependency.
eform-client/​src/​app/​common/​modules/​eform-cases/​components/​case-edit/​case-edit-element/​case-edit-element.component.ts Removes the circular module import.
eform-client/​src/​app/​common/​modules/​eform-cases/​components/​case-edit-nav/​case-edit-nav.component.ts Removes the circular module import.

Review effort: Balanced

@renemadsen
renemadsen merged commit 81e49d3 into angular19 Oct 18, 2026
33 of 37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants