Skip to content

Instantly share code, notes, and snippets.

@rooparsh
Last active April 3, 2021 09:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rooparsh/e9a44d450a038c7ea9e18277ad5cc328 to your computer and use it in GitHub Desktop.
Save rooparsh/e9a44d450a038c7ea9e18277ad5cc328 to your computer and use it in GitHub Desktop.
Handling Offline First Gracefully
import kotlinx.coroutines.flow.*
sealed class Result<out T> {
class Success<T>(data: T) : Result<T>()
object Loading : Result<Nothing>()
class Error(error: Throwable) : Result<Nothing>()
}
inline fun <ResultType, RequestType> networkBoundResource(
crossinline query: () -> Flow<ResultType>,
crossinline fetch: suspend () -> RequestType,
crossinline saveFetchResult: suspend (RequestType) -> Unit,
crossinline shouldFetch: (ResultType) -> Boolean = { true }
) = flow {
val data = query().first()
emit(Result.Loading)
val flow = if (shouldFetch(data)) {
try {
saveFetchResult(fetch())
query().map { Result.Success(it) }
} catch (throwable: Throwable) {
query().map { Result.Error(throwable) }
}
} else {
query().map { Result.Success(it) }
}
emitAll(flow)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment