which is the best approach for an offline first ap...
# coroutines
l
which is the best approach for an offline first approach?
Copy code
Case: I have to fetch from api (if fails)> from cache (if fails) -> catrastrophic failure handling
So first case would be something like Using lambdas
Copy code
fun getContent(){
		launch{
		    try{
		    val content =useCase.getContent(errorLambdaCallback= {handleError(it)})
			showContent(content)
			} catch(e:Exception){
			  handleError(e)
			}
		}
	}
Or use channels to communicate back that some error happened but the cache is retrieved? or there is actually a better way to handle this case where I need to handle error and get the content
h
I'm a huge fan of Either<T, E> in Scala, and would use kittinunf/Result in Kotlin for that. Now in 1.3, Kotlin has Result<T> included in stdlib. Have a look at it. Then you can do something like this: getFromApi(args).recover({error -> getFromCache(args)).fold({success -> ...}, {failure -> ...})
l
In fact I started to use it too, but I'm not too familiar with it so my repository is looking like this
Copy code
suspend fun getContent(erroCallback: (error:Throwable) -> Unit): Content {
        runCatching { apiService.getBalance().await() }
            .onSuccess { cache.set("key", it.content) }
            .onFailure { erroCallback.invoke(it) }
        return Content(cache.get("key",, "0"), "")
h
You could avoid an error callback if that fun returned Result<Content>.
Then your caller could fold or destructure and deal with the result. Unless you intend to have you method both call the errorCallback and return something (if I'm reading this right)
l
yes that correct I would like to return the error (for UI purposes like status Unauthorized) and the content either from Api or Cache
so the user receives the content but knows that is not up to date
do you think that might be possible without the callback?
the recover would work just fine If wouldn't need the actual error and just the result
h
Oh, I see now. UI context changes things a little bit. I've seen that concept in action in a React app, except everything runs with sagas. The app can run in happy mode, degraded status, and offline. You probably could, but it would involve writing a data class that could contain both a result and an error. And then you could differentiate between a hard error, a recovered error, and happy path. Pragmatically, it's probably fine the way you wrote it above.
l
yeah my first thought was to create a sealed classes to encapsulate that , but my fear I was to bloat the app with some kind of leaky abstraction or something like that
h
That's what I was thinking too. Good call.
👍 1