Search code examples
kotlinkotlin-js-interop

How to call a javascript function from Kotlin that expects a jQuery ajax settings object?


I need to convert the following code, it uses something in jQuery called an ajax settings (which is used in the javascript below inside the create() call to create a CouchDB database)

$.couch.db("mydb").create({
    success: function(data) {
        console.log(data);
    },
    error: function(status) {
        console.log(status);
    }
});

I have defined these

@JsName("$")
external val jq: JQuery

val jCouch: dynamic get() = jq.asDynamic().couch

but I am stuck on how to convert the javascript code

jCouch.db.create("mydb").what now?


Solution

  • There are several ways. First, you can create a dynamic object and set required properties there:

    val settings: dynamic = Any()
    settings.success = { data: dynamic -> console.log(data) }
    settings.error = { status: dynamic -> console.log(status) }
    jCouch.db("db").create(settings)
    

    (you may also specify corresponding type for data or status)

    Second, you can use json function:

    jCouch.db("db").create(json(
        "success" to { ... }, // edit note: added missing comma
        "error" to { ... }
    ))
    

    Third, you can write typed headers. I don't know what is Couch API, so headers would look approximately like that:

    external interface Db {
        fun create(settings: DbCreateSettings)
    }
    
    external interface DbResult
    
    external interface DbError
    
    external interface DbCreateSettings {
        val success: ((DbResult) -> Unit)?
        val error: ((DbError) -> Unit)?
    }
    
    fun JQuery.db(name: String): Db = asDynamic().db(name)
    
    fun foo() {
        jq.db("name").create(object : DbCreateSettings {
            override val success = { it: DbResult -> console.log(it) }
            override val error = { it: DbError -> console.log(it) }
        })
    }
    

    Finally, you can see how Kotlin stdlib declares headers for options