user2434385
user2434385

Reputation: 301

Callback with parameters with Kotlin

I just started Kotlin so please be nice :)

I have a class that is responsible for fetching some data and notify the main activity that its need to update its UI.

So i have made a function in my DataProvider.kt :

      fun getPeople(fromNetwork: Boolean, results: ((persons: Array<Person>, error: MyError?) -> Unit)) {

        // do some stuff stuff
        val map = hashMapOf(
                "John" to "Doe",
                "Jane" to "Smith"
        )

        var p = Person(map)
        val persons: Array <Person> = arrayOf (p)
        results(persons, null)
    }

So i want to call this from my activity but i can't find the right syntax ! :

    DataProvider.getPeople(
            true,
            results =
    )

I have try many things but i just want to get my array of persons and my optional error so i can update the UI.

The goal is to perform async code in my data provider so my activity can wait for it.

Any ideas ? Thank you very much for any help.

Upvotes: 10

Views: 18393

Answers (2)

dave o grady
dave o grady

Reputation: 822

Yes Kotlin has a great way of using callback functions which I will show you an example of how I use them below:

fun addMessageToDatabase(message: String, fromId: String, toId: String,
                                addedMessageSuccessHandler: () -> Unit,
                                addedMessageFailureHandler: () -> Unit) {



    val latestMessageRef = mDatabase.getReference("/latest-messages/$fromId/$toId")
    latestMessageRef.setValue(message).addOnSuccessListener {
        latestMessageUpdateSuccessHandler.invoke()

    }.addOnFailureListener {
        latestMessageUpdateFailureHandler.invoke()
    }
}

And finally you can utilise the new callbacks with the following code

databaseManager.updateLatestMessageForUsers(message, fromId, toId,
        latestMessageUpdateSuccessHandler = {
            // your success action
        },
        latestMessageUpdateFailureHandler = {
            // your failure action
        })

So basically when I successfully add a new row to my database I'm invoking a success or a failure response to the caller of the service. Hopefully this will help out someone.

Upvotes: 5

Zoe - Save the data dump
Zoe - Save the data dump

Reputation: 28228

This really depends on how you define the callback method. If you use a standalone function, use the :: operator. First (of course), I should explain the syntax:

(//these parenthesis are technically not necessary
(persons: Array<Person>, error: MyError?)//defines input arguments: an Array of Person and a nullable MyError
     -> Unit//defines the return type: Unit is the equivalent of void in Java (meaning no return type)
)

So the method is defined as:

fun callback(persons: Array<CustomObject>, error: Exception?){
    //Do whatever
}

And you call it like:

DataProvider.getPeople(
    true,
    results = this::callback
)

However, if you use anonymous callback functions, it's slightly different. This uses lambda as well:

getPeople(true, results={/*bracket defines a function. `persons, error` are the input arguments*/persons, error ->  {
        //do whatever
    }})

Upvotes: 13

Related Questions