dave08
02/09/2021, 3:05 PMkotlin-react-tutorial.js?92c2:40758 Uncaught TypeError: Cannot read property 'toString' of undefined
at _no_name_provided__132.invoke_223 (kotlin-react-tutorial.js?92c2:40758)
at _no_name_provided__83.eval [as _$render] (kotlin-react-tutorial.js?92c2:40780)
at _no_name_provided__83.invoke_132 (kotlin-react-tutorial.js?92c2:24110)
at eval (kotlin-react-tutorial.js?92c2:24149)
at buildElements (kotlin-react-tutorial.js?92c2:23965)
at _no_name_provided__84.invoke_134 (kotlin-react-tutorial.js?92c2:24124)
at VideoList (kotlin-react-tutorial.js?92c2:24136)
at renderWithHooks (react-dom.development.js?b313:14985)
at updateFunctionComponent (react-dom.development.js?b313:17356)
at beginWork (react-dom.development.js?b313:19063)
In here:
_no_name_provided__132.prototype.invoke_223 = function ($this$rFunction, props) {
var tmp0_iterator = props.videos.iterator_68();
while (tmp0_iterator.hasNext_49()) {
var video = tmp0_iterator.next_56();
var tmp0_p_0 = null;
var tmp1_tag_0_1 = _no_name_provided_$factory_98(tmp0_p_0);
var tmp0_apply_0_3 = new RDOMBuilder(tmp1_tag_0_1);
>>> tmp0_apply_0_3._set_key_(video._id.toString()); <<<<<<
var tmp0__anonymous__1_5 = tmp0_apply_0_3._attrs_0;
_set_onClickFunction_(tmp0__anonymous__1_5, _no_name_provided_$factory_99(props, video));
if (video.equals(props.selectedVideo)) {
tmp0_apply_0_3.unaryPlus_8('\u25B6 ');
}tmp0_apply_0_3.unaryPlus_8('' + video._speaker + ': ' + video._title);
$this$rFunction.child_4(tmp0_apply_0_3.create_11());
Unit_getInstance();
}
};
I'm using the IR compiler in dev modeMarc Knaup
02/09/2021, 3:37 PMclass Video
look like in Kotlin?dave08
02/09/2021, 4:00 PMMarc Knaup
02/09/2021, 4:02 PMandylamax
02/09/2021, 4:03 PMunsafeCast
So in your case, if you unsafely cast the id to an int
that might by the problem\dave08
02/09/2021, 4:03 PMdata class Video(val id: Int, val title: String, val speaker: String, val videoUrl: String)
dave08
02/09/2021, 4:03 PMval videoList = rFunction<VideoListProps>("VideoList") { props ->
for (video in props.videos) {
p {
key = video.id.toString()
dave08
02/09/2021, 4:04 PMMarc Knaup
02/09/2021, 4:04 PMdave08
02/09/2021, 4:04 PMvideoList {
attrs.videos = unwatchedVideos
attrs.selectedVideo = currentVideo
attrs.onSelectVideo = { video ->
setCurrentVideo(video)
}
}
andylamax
02/09/2021, 4:05 PMunwatchedVideos
dave08
02/09/2021, 4:06 PMval app = rFunction<RProps>("App") {
val (currentVideo, setCurrentVideo) = useState<Video?>(null)
val (unwatchedVideos, setUnwatchedVideos) = useState<List<Video>>(listOf())
val (watchedVideos, setWatchedVideos) = useState<List<Video>>(listOf())
useEffect(listOf()) {
val mainScope = MainScope()
mainScope.launch {
val videos = fetchVideos()
setUnwatchedVideos(videos)
}
}
dave08
02/09/2021, 4:06 PMsuspend fun fetchVideo(id: Int): Video =
window.fetch("<https://my-json-server.typicode.com/kotlin-hands-on/kotlinconf-json/videos/$id>")
.await()
.json()
.await()
.unsafeCast<Video>()
suspend fun fetchVideos(): List<Video> = coroutineScope {
(1..25).map { id ->
async {
fetchVideo(id)
}
}.awaitAll()
}
dave08
02/09/2021, 4:06 PMMarc Knaup
02/09/2021, 4:07 PMunsafeCast
. hmm]dave08
02/09/2021, 4:07 PMdave08
02/09/2021, 4:07 PMMarc Knaup
02/09/2021, 4:07 PMMarc Knaup
02/09/2021, 4:08 PMid
in JS but now it’s _id
in IR.Marc Knaup
02/09/2021, 4:08 PMkotlinx-serialization
to parse JSON from a server instead of unsafeCast
which is the curlpit here.Marc Knaup
02/09/2021, 4:09 PMdata class Video
to external interface Video
. That should work as well.dave08
02/09/2021, 4:12 PMThe property used to be namedwhy?in JS but now it’sid
in IR._id
dave08
02/09/2021, 4:13 PMdave08
02/09/2021, 4:13 PMexternal interface Video
would require me to write it in js?Marc Knaup
02/09/2021, 4:14 PMwhy?It’s an implementation detail how Kotlin properties are implemented in JS. So naming has changed from Legacy compiler to IR.
Marc Knaup
02/09/2021, 4:14 PMThe Video object is internal in the kotlin code... so external interface Video would require me to write it in js? (edited)No, you don’t need to implement it.
Robert Jaros
02/09/2021, 4:15 PM@JsExport
https://kotlinlang.org/docs/reference/js-to-kotlin-interop.html#jsexport-annotationMarc Knaup
02/09/2021, 4:15 PMexternal interface Foo { val bar: Int }
the following is sufficient in JS:
val foo = { bar: 1 }
A simple object.
And that’s returned as JSON by your API call.Marc Knaup
02/09/2021, 4:16 PMYou can useThere’s no need here. There’s nothing to export.@JsExport
Robert Jaros
02/09/2021, 4:20 PMMarc Knaup
02/09/2021, 4:26 PMunsafeCast()
for parsed JSON to data class
is really dangerous 😉
https://play.kotlinlang.org/hands-on/Building%20Web%20Applications%20with%20React%20and%20Kotlin%20JS/08_Using_an_External_REST_APISebastian Aigner
02/09/2021, 4:29 PMdave08
02/09/2021, 4:32 PMdave08
02/09/2021, 4:44 PMSebastian Aigner
02/09/2021, 4:45 PMdave08
02/09/2021, 4:45 PM@file:JsModule("react-player")
@file:JsNonModule
import react.*
external object ReactPlayer {
val default: RClass<ReactPlayerProps>
}
external interface ReactPlayerProps : RProps {
var url: String?
get() = definedExternally
set(value) = definedExternally
}
and I'm getting:
Uncaught TypeError: Cannot read property 'default' of undefined
at VideoPlayer.render_0 (kotlin-react-tutorial.js?92c2:40913)
at _no_name_provided__82.invoke_132 (kotlin-react-tutorial.js?92c2:24052)
at eval (kotlin-react-tutorial.js?92c2:24142)
at buildElements (kotlin-react-tutorial.js?92c2:23965)
at VideoPlayer.RComponent.render_1 (kotlin-react-tutorial.js?92c2:24073)
at VideoPlayer.RComponent.render (kotlin-react-tutorial.js?92c2:24076)
at finishClassComponent (react-dom.development.js?b313:17485)
at updateClassComponent (react-dom.development.js?b313:17435)
at beginWork (react-dom.development.js?b313:19073)
at HTMLUnknownElement.callCallback (react-dom.development.js?b313:3945)
dave08
02/09/2021, 4:46 PMdave08
02/09/2021, 4:47 PM@JsName("default")
was being used...dave08
02/09/2021, 4:52 PMimport react.*
@JsModule("react-player")
@JsNonModule
external object ReactPlayer {
val default: RClass<ReactPlayerProps>
}
external interface ReactPlayerProps : RProps {
var url: String?
get() = definedExternally
set(value) = definedExternally
}