How to convert JS code to Kotlin without the 'new' keyword

Viewed 5670

I'm looking into converting some basic JS to Kotlin but I'm stuck on the new keyword. I'm not sure how to convert the following JS to Kotlin

var FCM = require('fcm-node');
var fcm = new FCM('YOURSERVERKEYHERE');
var message = { ... };
fcm.send(message, function(err, response){ ... }

I tried

fun sendTestPush() {
  val FCM = require("fcm-push")
  val fcm = new FCM("YOURSERVERKEYHERE")

  val data = Data("Title", "Message")
  val message = Message("registration_id", data)

  fcm.send(message)
}

data class Message(val to: String, val data: Data)
data class Data(val title: String, val message: String)

I get the compile error Unresolved reference: new as Kotlin doesn't have it. Without the 'new' I get the expected error Attempting to TypeError: Cannot read property 'send' of undefined

Any idea to get around this problem?

Edit: FCM class is the npm package https://www.npmjs.com/package/fcm-push

3 Answers

Sorry but your answer you marked as correct, is in fact incorrect. I have to say this, since someone who is looking for the right answer might find it and write incorrect code. Generally, you shouldn't call the require function from Kotlin directly. Rather, you should use @JsModule together with external declarations. In your particular case it would be something like this:

@JsModule("fcm-push")
external class FCM(serverKey: String) {
   fun send(message: Any?, callback: (err: Any?, response: Any?) -> Unit)
   fun send(message: Any?): Promise<Any>
}

val serverKey = "YOURSERVERKEYHERE"
val fcm = FCM(serverKey)
//...
fcm.send(message)

Also, you should pass commonjs to the moduleKind compiler flag. See the corresponding documentation page for a full description.

Thanks to a hint from @Claies I managed get it to work using the js(...) wrap.~~~

val FCM = require("fcm-push")
val serverKey = "YOURSERVERKEYHERE"
val fcm = js("new FCM(serverKey)")
...
fcm.send(message) // now works

I'm not sure I'm totally happy with the writing pure js inside a string in kotlin so I hope there is a better way that I've missed.

Edit: The above works, but its not ideal, refer to accepted answer for better implementation

Related