Bam
02/10/2025, 3:43 PM//pseudo code
flowOf(1,2,3)
.onStartCheckAndThrowNoInternetException()
.map { it + 1 }
.catchNoInternetException()
.catch { //catch general error }
.collect()
The above code is what I am hoping to achieve, but the functionality to do the check requires a dependency. Or more dependencies depending on exactly what I want to do.
The point is that I want to be able to provide these extension function from a constructed class, where all logic is internal to the class, instead of having to provide all the dependencies here.Bam
02/10/2025, 3:48 PMclass CustomFlowCollector<T> @Inject constructor(
private val internetConnection: InternetConnection
) : FlowCollector<T> {
fun action() {
if (!internetConnection.checkConnection()) throw NoInternetConnectionException()
}
override suspend fun emit(value: T) = Unit
companion object {
fun <T> Flow<T>.onStartCheckAndThrowNoInternetException(
customFlowCollector: CustomFlowCollector<T>
): Flow<T> = onStart {
customFlowCollector.action()
}
}
}
Here's the usage for the above:
//pseudo code
@Inject
lateinit var customFlowCollector: CustomFlowCollector
flowOf(1,2,3)
.onStartCheckAndThrowNoInternetException(customFlowCollector)
.map { it + 1 }
.catchNoInternetException()
.catch { //catch general error }
.collect()
Youssef Shoaib [MOD]
02/10/2025, 3:48 PMclass MyConstructedClass {
fun <T> Flow<T>.onStartCheckBlah(): Flow<T>
}
// usage
with(MyConstructedClass()) {
flowOf(...)
.onStartCheckBlah()
.blah
}
Youssef Shoaib [MOD]
02/10/2025, 3:50 PMclass CustomFlowCollector<T> @Inject constructor(
private val internetConnection: InternetConnection
) {
companion object {
fun <T> Flow<T>.onStartCheckAndThrowNoInternetException(
customFlowCollector: CustomFlowCollector<T>
): Flow<T> = onStart {
if (!customFlowCollector.internetConnection.checkConnection()) throw NoInternetConnectionException()
}
}
}
Bam
02/10/2025, 3:52 PMwith
, but maybe I use that in some other way.
Any other suggestions are also welcome. 🙏🏼Youssef Shoaib [MOD]
02/10/2025, 3:53 PMFlowCollector
or any such "dangerous" APIs. It's just a good-old extension method. Its usage is exactly as you provided:
@Inject
lateinit var customFlowCollector: CustomFlowCollector
flowOf(1,2,3)
.onStartCheckAndThrowNoInternetException(customFlowCollector)
.map { it + 1 }
.catchNoInternetException()
.catch { //catch general error }
.collect()
Youssef Shoaib [MOD]
02/10/2025, 3:56 PMflowOf
with a with
btw. A with
just brings an object in as a receiver, so that it may be used to e.g. call member extension functions (in my first solution, onStartCheckBlah
is a member of MyCustomClass
, but it's an extension of Flow
, and so it needs MyCustomClass
in scope, while receiving Flow
either in scope or explicitly using the .
). Context parameters are also likely to help you here.Sam
02/10/2025, 4:12 PM(Flow<T>) -> Flow<T>
and then just apply it to the flow with let
.
flowOf(1,2,3).let(myHandler).etc()