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()