Skip to content

Instantly share code, notes, and snippets.

@Zeirison
Created April 25, 2020 12:10
Show Gist options
  • Select an option

  • Save Zeirison/b1b5f5f045dd39f9a30024c55d5682cc to your computer and use it in GitHub Desktop.

Select an option

Save Zeirison/b1b5f5f045dd39f9a30024c55d5682cc to your computer and use it in GitHub Desktop.
fun fetchProductDetailsById(id: Int) {
productDetailsState.set(ProductDetailState.Loading)
CoroutineScope(Dispatchers.IO).launch {
resultSingleFlow(
token = { userRepository.getUserAuthData().token },
database = { dao.getProductDetailsById(id = id) },
network = { token ->
api.fetchProductDetailsById(
token = token,
id = id
)
},
saveResult = { dao.insertProductDetails(it) },
mapper = { it.toEntity() }
).catch {
productDetailsState.set(ProductDetailState.Failed(it))
}.collect {
productDetailsState.set(ProductDetailState.Success(it))
}
}
}
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import retrofit2.Response
suspend fun <T, A> resultSingleFlow(
token: suspend () -> String,
mapper: (A) -> T,
database: suspend () -> T,
network: suspend (String) -> Response<A>,
saveResult: suspend (T) -> Unit
): Flow<T> = flow {
val data = database.invoke()
val isNotEmptyOrNullObject = data != null && data !is Collection<*>
val isNotEmptyOrNullList = data is Collection<*> && data.count() > 0
if (isNotEmptyOrNullObject || isNotEmptyOrNullList) {
emit(data)
} else {
try {
val response = network(token.invoke())
if (response.isSuccessful) {
response.body()?.let {
saveResult(mapper(it))
emit(mapper(it))
} ?: run {
error("Something went wrong")
}
} else {
error("Something went wrong")
}
} catch (e: Exception) {
error(e)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment