Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Covert lambda result to flow

I have the intention of converting the structure I am currently using to flow. It may sound silly or irrelevant to you.
Let me explain to you the structure:

  • I have an object named BleDataSource. For example, it has a function like below.
    fun performConnect(device: BluetoothDevice, result: ((Resource<BleOperationResult>) -> Unit)) {
        enqueueOperation(Connect(device, result))
    }

    fun callback() {
        if ( operation is Connect ) {
           if  ( erroroccured )
               operation.result(Resource.Error("error"))
           else
               operation.result(Resource.Loading())
        }
    }

    fun onetherCallback() {
        if ( operation is Connect ) {
               operation.result(Resource.Success())
        }
    }

  • This function saves to the job queue and connects to the device when it’s turn. I can report the current status of the job(For example Loading, Success Or Error) because I also save the result.

  • From repository i am using this function as below:

    MEDevel.com: Open-source for Healthcare and Education

    Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

    Visit Medevel

    override fun connect(device: BluetoothDevice, result: (Resource<BleOperationResult>) -> Unit) {
        handler.performConnect(device, result)
    }

But I want it to return as flow from the repository.

    override fun connect(device: BluetoothDevice): Flow<Resource<BleOperationResult> {
        handler.performConnect(device) {
        }
    }

How can I do that? (according to recommandation i can also edit the BleDataSource class)

>Solution :

If I understand correctly, it looks like a classic case of converting a "multi-shot" callback function to a flow.

This can be done using callbackFlow:

fun BleDataSource.connect(device: BluetoothDevice): Flow<Resource<BleOperationResult>> = callbackFlow {
    performConnect(device) { res ->
        channel.send(res) // or trySend + error handling
    }
    awaitClose()
}

The problem is that I don’t see a way to unregister the callback from the API you provided. Once you called performConnect with a lambda, it looks like this lambda listener cannot be removed. If there is a way to do that, you should do it in the lambda passed to awaitClose { ... }.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading