fix(dashboard): skip null-value portfolio points instead of plotting 0#694
Merged
Merged
Conversation
A historical balance point with a null value in the selected currency means the API could not price it (e.g. quote currently unavailable), not that the holding is worth 0. Mapping null to 0 made the chart line crash to zero and the performance box show a false -921 CHF / -100% drop while the header correctly rendered "--.--". Skip points whose value is null so the chart ends at the last known value and the change is computed against it. A genuine 0.0 value (balance held but worth zero) is preserved and remains distinct from null.
3 tasks
TaprootFreak
added a commit
that referenced
this pull request
Jun 5, 2026
… price chart (#695) ## Problem The public price view ("RealUnit Aktienkurs") shows an **empty chart** and `CHF --.--` whenever the RealUnit quote is temporarily unavailable. Confirmed against the live API: - `GET /v1/realunit/price` → `{"timestamp":"2026-06-04T22:28:16.539Z"}` — **no `chf`/`eur`**. - `GET /v1/realunit/price/history?timeFrame=ALL` → **1514 points, 1513 valid**, only the latest (2026-06-04) has no `chf`/`eur`. `DFXPriceService.getPriceChart` did `BigInt.from(entry['chf'] * 100)` for every entry, so the single null point threw (`null * 100`), the whole method threw, and `priceChart` stayed `[]` → the entire history (1513 valid points) was discarded and the chart rendered empty. `getPriceOfAsset` threw on the same null. This is the same defect class as the portfolio-chart fix in #694, but in the **price** code path (`dfx_price_service.dart`), which #694 does not touch. It is more visible because it affects the wallet-less public price view. ## Fix - `getPriceChart`: skip entries whose selected-currency price is `null` instead of throwing — the chart renders the full history minus the unpriced tail point. - `getPriceOfAsset`: return `BigInt.zero` when the price is missing, so the UI renders `--.--` instead of throwing. - `getChfToEurRate`: treat a missing `chf`/`eur` as `0` (already guards `chf > 0`). ## Tests - `getPriceChart` skips a trailing null point and keeps earlier valued points. - `getPriceOfAsset` returns zero on a missing price. - `getChfToEurRate` returns `0.0` on a missing price. - `flutter analyze` clean; price-service + price-chart-cubit suites green (22 tests). ## Test plan - [ ] Open the app with no wallet while the quote endpoint omits `chf`/`eur` → price chart renders full history, header `--.--`, no empty chart. - [ ] Normal case (all prices present) → unchanged. - [ ] Current price endpoint without `chf`/`eur` → header `--.--`, no crash. ## Related - Sibling fix for the portfolio chart: #694 (same null-handling defect, account endpoint).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When the REALU quote is temporarily unavailable, the dashboard showed a corrupt portfolio chart: the line crashed to 0 at the most recent point and the performance box reported -921.27 CHF | -100.00%, even though the header correctly rendered the total as
--.--.Root cause: the API returns
valueChf/valueEurasnullfor points it cannot price.RealUnitAccountService.getPortfolioHistorymapped thatnullto0(value ?? 0). The latest history point (balance still held, pricenull) was therefore plotted as a zero-value point, dragging the chart to the x-axis and making thelast - firstperformance calc read-100%.Fix
nullin the selected currency instead of mapping them to0. The chart now ends at the last known value and the change is computed against it; the header keeps showing--.--(already handled).0.0value (balance held but worth zero) is preserved and stays distinct fromnull(unknown).Single change at the API boundary — no chart/cubit/widget changes needed, since the false
0originated in the service mapping.Tests
treats a null value as 0test →skips a point whose value is null(point is dropped).keeps a genuine 0.0 value (distinct from null).drops a trailing null point but keeps earlier valued points.flutter analyzeclean; dashboard + dfx service suites green (516 tests).Test plan
nullfor the latest point → chart stays at last known value, header--.--, no-100%.