Aman-Mittal opened a new issue, #184:
URL: https://github.com/apache/fineract-backoffice-ui/issues/184
## Summary
Across the application, component state that is assigned from an HTTP
callback is held in plain
class fields and read directly by the component's template.
`scripts/audit-async-state.mjs`
counts **429 such fields across 184 components**. This issue tracks
converting all of them to
signals, along with the remaining decorator-based `@Input()` / `@Output()`
declarations.
## Business value
**This is a correctness problem, not a style preference.** Angular 22 makes
`OnPush` the default
change-detection strategy: a component that does not declare
`changeDetection` *is* `OnPush`.
Assigning a plain field from a `subscribe` callback changes the value the
template reads without
marking the view dirty, so the new value renders only if some unrelated
interaction happens to
trigger a check.
The user-visible symptom is a screen that silently shows stale or empty data
— an API-fed dropdown
that renders zero options, a detail panel that stays blank after the record
loads, a saved change
that does not appear until the user clicks elsewhere. In a loan servicing
back office these are
not cosmetic: an officer who cannot see a product option or an outstanding
balance cannot complete
the operation, and there is no error message pointing at the cause.
Concretely this delivers:
- **Data that is on screen when it arrives**, on every screen, rather than
on the ones that happen
to get an extra change-detection pass.
- **A working `NG0100` signal in CI.** The e2e fixture already watches for
`ExpressionChangedAfterItHasBeenChecked`. While hundreds of fields
legitimately produce that
error, the check has to stay advisory. Once the count is zero it can be
enforced, and the next
regression of this kind fails a pull request instead of reaching a user.
- **A pre-condition for `provideZonelessChangeDetection()`.** Zone.js
currently provides a second,
accidental trigger that masks these fields. Removing zone.js without
converting them first would
break every one of them at once, so this work has to land before that
change can be considered.
- **A clean lint gate.** `eslint-suppressions.json` exists to hold
pre-existing violations of
`@angular-eslint/prefer-signals`. Emptying it means new violations are
caught on the pull request
that introduces them, instead of being absorbed into a baseline.
## Scope
- Convert all fields reported by `scripts/audit-async-state.mjs` to
`signal()` / `computed()`.
- Replace the remaining `@Input()` / `@Output()` declarations with
`input()`, `output()` and
`model()`, and the last `ngOnChanges` with an `effect()`.
- Split `[(ngModel)]` bindings that now target a signal into `[ngModel]` +
`(ngModelChange)`, since
a signal cannot be a two-way binding target.
- Reduce `eslint-suppressions.json` to empty.
### Modal components
Dialogs are the blocker for the input conversion. Ionic delivers
`componentProps` with
`Object.assign` unless `useSetInputAPI` is enabled, which would overwrite
the `InputSignal` on the
instance with the raw value and leave the template calling a plain object.
Enabling it lets the
dialog family move to signal inputs; it requires every key passed through
`DialogService.open` to
be a declared input on the target component.
## Acceptance criteria
- [ ] `node scripts/audit-async-state.mjs` reports 0 fields.
- [ ] No `@Input()` / `@Output()` decorators or `ngOnChanges`
implementations remain outside the
generated API client.
- [ ] `eslint-suppressions.json` is empty and `npm run lint` passes with
nothing suppressed.
- [ ] `npm run build` succeeds — it is the only check that type-checks
templates, so it is what
catches a signal read that is missing its call.
- [ ] The unit suite and the mocked Playwright project both pass.
## Verification
```bash
node scripts/audit-async-state.mjs # expect: 0 plain fields across 0
components
npm run lint # expect: clean, with an empty
suppressions file
npm run build # type-checks every template
npm run test -- --watch=false --browsers=ChromeHeadless
--project=fineract-backoffice-ui
npx playwright test --project=mocked
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]