apache / apache/fineract-backoffice-ui

A failed list load looks identical to an empty list on 65 screens

Open Beginner friendly
#223 5 comments 0 reactions 0 assignees View on GitHub
angular bug good first issue javascript typescript ux
Dominant language
TypeScript
Stars
15
Forks
60
Avg merge
10h 15m
Merged PRs (30d)
108

Description

## What is wrong

`` accepts a `[hasError]` input and emits `(retry)`. Together they turn a failed
load into a message with a retry button instead of an empty table.

**65 of the 78 screens using the shared table bind neither.** When the request fails they call
`catchError(() => of([]))` or similar and render zero rows — which is exactly what a genuinely
empty list looks like.

For a back-office user the difference matters: "this client has no charges" and "we could not
reach the server" lead to completely different next actions, and right now the screen says the
first when it means the second.

## Where to start

Any of these. One screen per pull request:

- `accounting/charges/charges-list.component.ts`
- `accounting/accounting-rules-list.component.ts`
- `accounting/accounting-closures-list.component.ts`
- `accounting/provisioning-categories/provisioning-categories-list.component.ts`
- `calendars/calendars-list.component.ts`
- `clients/charges/client-charges-list.component.ts`
- `clients/collateral/client-collateral-list.component.ts`

Full list:

```bash
for f in $(grep -rl "app-data-table" src/app/features --include=*-list.component.ts); do
grep -q "hasError" "$f" || echo "$f"
done
```

## What to change

The pattern is in `src/app/features/products/loan-products-list.component.ts`:

```ts
readonly hasError = signal(false);

private loadProducts(): void {
this.service.getThings()
.pipe(
tap(() => this.hasError.set(false)),
catchError(() => {
this.hasError.set(true);
return of([]);
}),
)
.subscribe((data) => this.products.set(data ?? []));
}

onRetry(): void {
this.loadProducts();
}
```

```html

```

Note `tap` resetting the flag on success — without it a screen that fails once shows the error
banner forever, including after a successful retry.

## How to check it

`e2e/list-pagination.spec.ts` has a worked example under *"List load failure"*: it fails the first
request, serves the second, asserts `data-table-error` appears, then that retry restores the rows.
Copying that shape for the screen you convert is the best way to show it works.

```bash
npm run test -- --watch=false --browsers=ChromeHeadless --project=fineract-backoffice-ui
npx playwright test --project=mocked
```

## Why it is worth doing

Silently swallowing an error is the failure mode users cannot diagnose and support cannot
reproduce. This is a handful of lines per screen and turns a dead end into a retry.

Good first issue: pick one screen, follow the pattern, add the spec.

Contributor guide

Open the contributing guide

Research direction

Pick one listed *-list.component.ts file and compare it with src/app/features/products/loan-products-list.component.ts. Add the hasError reset, failure handling, retry binding, and a spec following the “List load failure” example in e2e/list-pagination.spec.ts. Run the mocked Playwright test and verify data-table-error appears on the first failure and rows return after retry.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, playwright, typescript
Domain
frontend, testing
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
86/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.