Numbers Alone Were Not Enough to Trust Public Data
Why remaining spaces and congestion needed sources, updated times, and explicit unknown states beside them.

In an app that uses public data, saying “accurate information” is not enough. Especially in an app like Hangangjari, which helps people decide whether to move and stay, one number can lead directly to action.
If remaining parking spaces are shown as 20, users feel they can bring the car. If congestion looks low, they think it is okay to go now. If an event appears today, they may change destinations.
So the values on screen were not just data. One number, one label, and one updated time combine into thoughts like “I can go” or “I should avoid it today.”
The problem is that public data does not always arrive with the same speed or meaning.
Some values were just updated. Some were slightly old after the last successful collection. Some came from a live source but had no item for that park. Some came from a failing source and were hard to trust at the moment.
If all of these differences are flattened into “no information,” the app becomes indifferent. If stale values look current, it becomes more dangerous.
So in Hangangjari, I tried not to show only numbers. Three things had to appear with the number.
- Updated time.
- Source.
- An admission that the app does not know.
Numbers need observation time beside them
Numbers are strong on a screen. A phrase like “20 spaces available” reads like a conclusion even without explanation. But parking lots keep changing while users are checking. Events, controls, weather, and time of day can also make the situation differ from usual.
That is why a number needs its observation time. The screen needs to say when the value was observed, when it was last fetched successfully, and whether it is old.
Status labels are the same. “Available,” “normal,” “crowded,” and “full” are not pretty names that replace the number. They are supporting signals that help users interpret it. When remaining spaces and status appear together, users can read the situation more realistically.
I also decided not to hide sources. Hangangjari receives data with different purposes: parking, real-time context, events, facilities, and notices. Each has a different role and update speed. If event lists, real-time congestion, and facility state are blended as one kind of information, the screen may look simpler, but users cannot know how much to trust each piece.
The reason for missing information mattered
What to show when data is missing mattered more than expected. To a developer, null, empty array, timeout, and 404 are all different. To users, they can all look like an empty screen. But what the user should do next differs.
If a park has no parking lot, the user should look at public transit or nearby lots. If the park has parking lots but no real-time availability, total capacity and location may still be useful.
If a source temporarily failed, the user can check again later. If the last successful value is old, the user should account for on-site changes.
So I did not want to end with one “no information” message. Screen copy has to be short, but that short sentence should still imply what to do next. “Collection is currently delayed” and “This park does not provide real-time parking information” look similar, but they are completely different messages.
| What the screen should say | What the user can do |
|---|---|
| The value was just updated | Treat the current value as primary. |
| The last value is slightly old | Account for possible on-site changes. |
| The source temporarily failed | Check again later or look at other information. |
| This park has no such information | Look at transit, facilities, notices, or other information instead. |
| The source is not connected yet | Do not hide that the app does not know. |
After writing this out, data state was no longer developer-side exception handling. It became wording that changes what users look at next.
When the app does not know, it should say so
The hardest part was how to say that the app does not know.
Empty data can have different reasons.
The park may not have parking. It may have parking, but no real-time remaining-space data. The source may be temporarily failing. The last successful value may be too old and usable only as a reference. The product may not have connected that source yet.
Users care about these differences. “Parking information not provided,” “collection currently failed,” and “stale information” all create different actions. One leads to nearby alternatives, one invites a later check, and one asks the user to account for on-site changes.
This distinction entered the API response and screen guidance. Internally, sections have states such as fresh, partial, stale, and unavailable, plus updated time, last successful time, and source status.
The app should show what it knows while also showing how far its knowledge goes.
I do not show internal state names directly to users. stale is a good developer name, not a good user phrase. On screen, it should become wording like “based on the last check” or “updates are delayed.” But the internal names still need to exist so the app, widget, and notifications treat the same value with the same meaning.
Users do not need to know every detail of a data source, but they should feel how much confidence the app has in the value it is showing.
Hangangjari is not operated by an institution. It is an independent app based on public information and data I organize directly to help decisions before and during a visit. That makes it even more important not to speak definitively. More than “this is correct,” the important question is when and where a value came from and how much it can be trusted right now.
Updated time and source reduced anxiety
At first, I worried that showing updated time and source would make the screen messy. But while using the app myself, those small cues made me feel calmer.
Was this from a few minutes ago? Which source is it based on? Is it stale? Is the value absent, or did fetching fail?
When users know this, they do not blindly trust the app; they make their own judgment. The app should not over-decide for users. It should honestly organize what to check before and after moving.
In Hangangjari, data trust was not only a backend or parser problem. Screen guidance, status labels, widget display, and notification rules all had to carry the same attitude.
Trust does not come all at once. It forms on days when numbers are right, and also on days when the app says it does not know. When the app does not hide the range of what it does not know, users can treat values realistically instead of overtrusting them.
Notifications had to be even more conservative
Notifications are more sensitive than screens. Showing stale values inside the app is a problem, but sending a notification based on stale values is worse. Users treat notifications as action signals.
So notification candidates also needed freshness and source status checks. It was not enough to say “remaining spaces fell below the threshold.” The server also had to know when that value was confirmed, whether recent collection was healthy, and whether a similar notification had already been sent.
In the end, data trust was not a small helper line on the screen. It was a safety device for the whole app. Saying only as much as the app can trust mattered more than saying it is accurate.
The biggest lesson from building a public-data app was this: a good data app is not one that shows a lot of data. It is one that understands the weight of the value it is showing right now.
For Hangangjari, accuracy was not about matching a single number. It was about showing numbers, updated times, and sources together, and making clear how far users can trust them.
Share
No comments yet. You can leave the first one.
Pending review