A single mutually exclusive Loading, Success, or Error value can be too coarse. The screen may simultaneously have useful saved lessons and a failed attempt to refresh them.
A possible screen model, with an existing Lesson domain type:
data class LibraryState(
val lessons: List<Lesson> = emptyList(),
val hasLoaded: Boolean = false,
val isRefreshing: Boolean = false,
val refreshError: String? = null
)
Observe persisted lessons as the content source. Refresh writes successful results into storage. If it fails, retain existing content and show a retry affordance. A first-load failure with no content needs a different presentation from a refresh failure with 30 readable lessons.
hasLoaded distinguishes an uninitialized list from a successful empty result. In a production model, a typed error can carry recovery information while the UI selects localized messages.
Cached content is not always safe to act on. Showing a saved lesson title is different from trusting a stale entitlement or checkout price. Define which actions require revalidation and communicate unavailable actions explicitly.
What should a successful empty refresh do? If the API response is authoritative, update the relevant stored result set to empty. Preserving stale content on failures must not become a rule that ignores legitimate deletions.
Mark this when you can explain the answer in your own words.
Help fellow developers prepare for interviews
Sharing helps the Android community grow ๐