KotlinConf 2017 - How to Build a React App in Kotlin by Dave Ford

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] all right can you guys hear me I have to get fast this is my first time ever using a microphone like this so when I go for questions I'm gonna have to remember to either give you guys a microphone or repeat the question so if I forget please remind me my name is Dave thank you all for coming let's start on I want to ask you guys a couple questions how many of you guys are already coding in Kotlin raise your hand all right almost everybody how many of you are already experienced react programmers about half how many of you guys used or have used them create react app ah okay only if only yeah better quarter how many of you have done any Kotlin to JavaScript compiling apps ah so everybody's new to that okay so that means you're probably doing Android or server-side I'm guessing anybody used any of Kotlin typesafe builders alright so not much with that okay then that probably means you haven't used this either so don't even worry about that all right so now I know where you guys are I'm going to start with just a little bit of overview of on why this is a useful thing so 80% of my coding over the years has been spent on doing this one thing and that is writing code in one language whose sole purpose in life is to spit out another language in this case HTML that's literally how I spent 90% of my career over the last you know gazillion years there's lots of ways to do that and interestingly enough nobody's really come up with a great way to do that until Kotlin a little bit react so in the old days I used to do string building I'd write java servlets or I'd write JavaScript that would build a giant string you guys ever do that that's that doesn't that's got a lot of problems you don't get any type checking your linting tools don't help you refactoring of course it doesn't work on there's security problems with injection and so forth then beyond that you have tree building you can use the Dom API right to say create element appended node append a node appended node is anyone ever created you eyes that way because of course HTML is a big tree right that's a huge pain table that's kind of worse than tree building because it just it's messy and huge and takes up tons of space then we had templates Java server pages angular and you will never use those products so templates are sort of the modern state of the art until what we're about to do so with templates those solve a lot of problems but here's the deal with templates a template the definition of a template is you have like a static part and then blue parts to change right but if you use templates after a while you're going to start to realize well I have some I have some things that repeat so your templating language is gonna need to have like a for loop added to it and of course you have some some things where I only want this display you know if it's Tuesday or if X is greater than 3 so you need some kind of if statement right and possibly a switch statement so now your template language has a nice famous switch statement a looping or some kind of repeat mechanism then your templates are gonna get big they're getting huge and you're gonna want to organize them and break them down into different pieces so now you gonna have some kind of you need some kind of mechanism for decomposition to take your big templates and break them into small templates right and so your template leaving language is gonna need that and then you might decide well I want to reuse some snippets of HTML right so now your templating language is gonna need some mechanism to achieve reuse or UI components if you will and what you realize is after a while your templating language is evolved into a complete full-on programming language and it's usually a bad programming language of that so those are the three things up till now and of course the first thing is before I get to the fourth thing I always like to give my spiel on separation of concerns I think since at least half you said your reason react this spiel may not be totally necessary but um some people have been taught that it's a good idea to separate UI from business logic raise your hand if you've heard that so that's pretty good advice but there's a kind of a subtle misinterpretation of that which would be separating angle braces from curly braces you're with me on that and in my opinion that's really stupid so it's definitely a good idea to separate stuff right to separate stuff that that should be evolving separately such as your business logic and your UI for testing reasons and and maintainability but that's different from mixing HTML with JavaScript in this case mixing HTML with Kotlin there is absolutely nothing wrong that doesn't violate any best practices or any design so a lot of people misinterpret this separation of concerns and so by bringing that up to prevent people from getting a distaste for something based on misunderstanding a a best practice all right so with that said I think the best way to write code that generates HTML in the year 2017 is to use internal dsls react adds in the internal DSL called JSX to JavaScript that's a big part of what react does right it allows you just put JavaScript or put HTML in JavaScript and I'm just giving you my wholesale pitch on why that I think that isn't a bad idea so Kotlin has its own thing it's always has its own thing it's always had the ability to do internal dsls just like JSX except it looks different and so that's what we're gonna do so this this kind of thing is realists these slides are kind of more like why react and I'm not gonna spend too much time on this because this is react Kotlin I kind of borrowed some of these slides so there's what JSX looks like just a melding of angle braces and curly braces and Kotlin looks pretty much similar same basic idea so if you think mixing if statements and for loops inside of your HTML is a bad idea then this isn't for you like I said I think it's a it's a best practice not a I'm not something shy away from and this part is just about react in general so the key idea between behind react is that you define your user interface your view as a function of the model so it's pretty functional you'd create your view as a function and then the idea what the react is and this is the magic of react if you ever want to update your UI you don't you never ever ever update your UI in react what you do is you write a function that takes your your data structures and turns those into a UI then when you want your UI the update do you update the UI or do you just update the one the model and then the UI magically redraws that's the magic of react that's what react gives you that make sense so we just said that never update the UI and the third thing is components I started out programming many years ago and I remember I did a visual basic class that's how old I am and we learned how to create reusable UI components and visual basic so in a five day Visual Basic class day five was how to create a reusable UI component and it took all day it was advanced material same was true when I was doing JavaServer faces and JSP and all sorts of things so even angular one has a lot of ceremony with creating a reusable piece of UI this is going to be the most awesome elegant reusable UI key bugs you've ever seen ever with the lowest amount of ceremony so with that said I'm gonna jump right into my demo here okay react with Kotlin you already saw he stole a little bit of my thunder in the beginning there there's a new tool called crate react Kotlin app that is modeled after something called create reactive for those of you who know react you might know that has a reputation for the configuration being a nightmare you know how in Java we have the Gradle or the maven or the answer nightmare well in JavaScript applications that have a build process probably the most popular tool is called web pack and that's even worse nightmare and so create react app as a tool by Facebook that basically assumes a bunch of defaults and hides you completely from that there is no build file make sense it still uses the same tool behind the scenes but it's hidden from you what Kotlin just can't what JetBrains just came out with is an equivalent tool for react with cotton and it's called crate crate react hotline app it's this Villere is a huge huge game-changer as you can see also there's some react wrappers there's some classes that they pre-made in Kotlin to make it easier for you to use react to be honest they just updated those a few days ago and I updated my presentation to use the latest and greatest ones that they have and then Cotton's typesafe builders those are a feature that have been part of Kotlin since day one so those are the kind of the aspects that we're gonna be using so from here on in let's create some code alright step one is by the way if you have any questions ask if anytime interrupt me raise your hand just jump in alright just make sure I remember to repeat your questions alright so we're gonna use create react app the first thing you have to do is install it so to install create react app I thought I had a slide for oh I do you're going to use NPM install you'll install it as a global library crate react app is actually two things you're installing one of them is installed globally one of them is installed locally as part of your app and when you run this it actually when you install it installs both but every time you run crate react tap the local part is pulled from the most current version so in other words installing this globally you'll probably never ever change it because the part that gets updated frequently is automatically sucked down every time you run it so with that said we're gonna run create react app can you guys see my screen okay so that's how you run it it's a command line tool I've already installed it I type that I was smart and I hooked up my verizon ahead of time that's gonna create a folder called my app it could be whatever you want but I call it my app this is just kind of a example name and then I'm gonna open that folder and Intel J so it doesn't just create an app it creates an with like the IntelliJ stuff already in there so it's a Nutella day project and it gives you some instructions I'm using yarn which is a kind of a drop-in replacement for NPM so it's telling you what you have to do so let's do that CD into the folder it just created and then we run yarn start or NPM start it figured out that I'm using yarn and gave the instructions accordingly if you were using NPM it'll give you a little bit different instructions and then I run it so how many of you again who raise your hand some create react app I think it was about a third maybe a quarter so the way Crate react works is it hides all the all the build files from you and also it creates a little thing where it monitors your app on your files and when they change it refreshes this screen in normal create react app it's instant in Kotlin it's still kind of got a delay so it's probably catching up speed wise so that's the app it created so let's open it up in IntelliJ something open there's a new folder there called my app okay this is the source code for this app he kind of showed some of this already in the UM in the opening keynote so I'm gonna kind of do my presentation a little bit different I'm not going to show all that so this is all the code necessary to create that app when I learned things I like to start from hello world and build up as opposed to start with something complicated and then I'll figure it out so I'm gonna build it that way so I'm gonna basically delete everything I'm delete everything that's not absolutely essential for a hello world I'm not saying those are things necessarily want to always delete but what's left here I'm gonna get rid of that I'm gonna get rid of this not get a delve into the cs1 new Delvin to see us a little bit how's my form can you see it okay all right so what render is this is part of the react cutland stuff that JetBrains is providing us it takes two arguments one is a the element that you're gonna stick your stuff into just like in normal react and the other is some HTML or raft components which are given in the form of a of a lambda function so let's say H 1 : so boom you're now seen reacts or ash as a Kotlin react version of JSX it's based on lambdas okay so I'm basically calling a function h1 that function takes one argument which is itself lambda and inside of that lambda is where I put all of its children does that make sense so how do i define children well if it's a text child I just use the plus operator and I'll say blackjack because we're gonna be making a little blackjack example alright good so this is all we have in our project is this and there's an HTML page which basically includes the JavaScript that's going to be generated the HTML page is actually to be honest it's generated as part of the build process and a script tag attaching to the generated script is inserted for you so you really even don't even need to look at the HTML page it's just a plain old HTML page with pretty much nothing in it but a title and some other just paperwork stuff alright here we go are you ready hahah yes so there's your hello world react application any questions so far yes yes yes that's exactly what they are so um to use this technology the react countin stuff you don't need to know too much but if you're like me you might want to understand it just but we only have 45 minutes there are some advanced Kotlin features used here that are interesting and if we have time I'll go into it but um let's add some more to this so does everyone understand I'm invoking a function called h1 and passing it one argument of type lambda now inside of this lambda so one of the advanced features is lambdas when you when you call a lambda you can actually change its this you could tell it what this to use so in other words this lambda function it's just a function like any other function and it's passed an argument but it's not passed a normal argument it's passed an argument to be used as its what as its this why is that important well that's why the plus operator works and that's also why this works so basically all the cool HTML stuff we want to do is basically part of the this which is magically thrust upon the lambda function you are defining so let's build on let's make a couple hands we're gonna have a player hand and a dealer hand so the game we're creating I already have the the business logic written so you have a game each game contains a player hand and a dealer hand that's pretty much all you need to know at this point also each hand contains an array of cards so that's the whole business model game player hand dealer hand car card card card card good alright with that said let's make some code for the hand so I'm gonna say div so first I'm gonna say let's see so this is gonna be hand I'm gonna say div and then inside of the div I'm gonna do that what's that tag do that makes it bold so then I'll say Plus play your hand then at the bottom of the player hand I'll say 12 points I'm hard coding it for now and then here I'm going to say the list of cards goes here but I don't have that we're gonna come back to that alright so there's one hand good let's see if that works now notice I didn't have to do a build I didn't even have to do a refresh it automatically does all that stuff for me that's part of the webpack magic that it's I'm doing behind the scenes also if you remember I deleted everything we didn't need notice what you don't see here you don't see a great old file you also don't see a web pack config file so the crate react Kotlin app tool provides all that for you in benefit trading a react app is awesome and super easy to do what's the drawback not as configurable right so that's kind of a trade-off you have to make alright so we got that going so far [Music] aha I'm trying to figure out why is everything giant so let's make this a div do you see how I put everything inside of the h1 I do that to see if you were paying attention did any of you catch it good job all right so I want to put my h1 starting here and then ending here so this is essentially like like my closing h1 tag cool all right let's see if it looks a little bit more like what I was expecting all right good now let's make the dealer hand like I said I'm hard coding just for phase one here so there's my dealer hand all right good now I want them to be side by side one thing I haven't shown you is how to do attributes so you now know how to make a tag you also know how to give that tag children correct but as you know tags or elements have children but they also have attributes here's how you do attributes I'm going to go here and say attributes dot that's how you do an attribute that makes sense so title that's like the tooltip so in theory if I run it now I should be able hover over anything and have that title pop up is pardon me No so it's some yeah that's the whole typesafe thing oh the question was can I add any arbitrary attribute and the answer is no there is so actually by default they give you the the built-in ones and so it's type safe and you get Auto completion all that you are you could do something to be honest they just updated through this three days ago so as or three days ago you could do this and that doesn't seem to work but I'm sure there's some equivalent to do it so I don't know what it is so you could do both you could do ones that it doesn't know about or or you could do the ones that it knows about this way that make sense so I'm sure there's some way to still do that does anybody know what it is yeah so they just changed the API a little bit ago so it used to be attributes is what it was let's actually it was it was actually attributes and that's not even there anymore so yeah so there was three days ago but I decided to update it just so I could use this create react app stuff in my demo here all right moving on I don't really want to do a title what I really wanted to do is a style now this is a little bit weird I'm gonna make the assumption this will probably evolve to be something a little bit more useful as time goes on but you might know that in normal HTML this is a string in react it's not a string it's a JavaScript object that makes sense so what I'm gonna do is I'm gonna use something called um Kotlin ext J SJS and that's going to allow me to define a JavaScript object on the fly this is not typesafe this allows you to randomly type whatever you want so I'm gonna say display equals flex you'll notice I could say that and it would work just as easily so this is a little bit different that makes sense so this is this is special just for stuff because react has some special stuff for style and so does this so I'm passing in a JavaScript object I want to import this so I don't have to type that in every time so then it ends up looking like that now it's giving a warning and I also hope they'll fix this because this literally this feature just came out very recently but for now just to shut up the warning I'm gonna say suppress this warning for the files for the file and it adds that up there alright so this is how you do local CSS in Kotlin react any questions so far pretty cool huh now one thing that's on the Dave witch list on my wish list is something to do this in a type safe way I used to use GWT which is very similar in concept to what this is trying to do Google web toolkit allows you to do Java to JavaScript compilation and it had a whole set of classes for typesafe CSS which was wonderful I really like using that hopefully they'll add that to this if not maybe one of you guys will develop it in the open source all right so let's make sure it's so also flex will do is make them side by side instead of on top of each other so now my hands are side by side did it work all right now you're probably noticing that this guy and this guy look a lot alike correct so in my opinion one of the best things about react and react Kotlin is the amount of ceremony to create a reusable UI component either for the purpose of reuse or for the purpose of organization creating UI components is easier in this technology than anything in the history of the universe ever so it's literally just a function now I'm about to create that function and there might be some weird syntax that you haven't seen before so and I'm not going to go in too much depth about it but let me just say in written Colin you could pass arguments right but you can also pass a this and so it's declared and kind of strange way it's a declared similar to an extension function all right now these functions are functions that um that we will be calling but this is just kind of implicitly passed in so with that said I'm gonna grab this and I'll say extract that's gonna be this and I'm gonna call this function um hand UI that's just my own Dave naming convention because UI only requires two letters and I also have a hand thing that's like a business object and so I don't want to get them mixed up so there you have it so this is that thing I was talking about does that make sense this this shows that this function takes one argument but it's not a normal argument it's the what argument love this argument and that is why I can without any kind of special prefix I can call what function div does that make sense you don't have to do this you could pass the stuff in directly the old-fashioned way which I did at first because I didn't get this syntax and it was bugging me but now that I'm used to and I'm happy with it I use it all the time so so again this is a whole separate topic but we're just passing an argument and happens to be an argument that is gonna be referenced the way this would be referenced all right so that's what this is all right now we'll call it twice yeah question is that creating a custom HTML element no it's not creating a custom HTML element in the sense of it could be called from like a plain HTML filed as a tag and it's also not creating a custom element in terms of the web the w3c custom elements spec so no it's basically doing what you would do in react so no more so than in react all right so I'm gonna take this and I'm gonna try to emulate more of a real-life situation in which you know this UI could get big and I'm gonna make it its own file so I'll go over here and I'll make a new folder called blackjack and in it I'll make a new column file called hand UI and I'll paste this in there like so now this is small enough I don't really need it but I just want to show you how this might look in more of a realistic app I also don't want to get those warnings so I'll put that in there as well actually I don't have any warnings there but I'm about to alright so now I don't need this anymore and I need to import this because it's in a different package like so cool now I'm going to create this and put this in a different package I'm going to call that game view so remember have a game a hand in a hand and the UI is the same thing game you I hand you I hand you aya like so and I'm gonna copy this whole thing right here and here and I'll make this one manual so I'm going to say game UI / imporant like so and I need that I need that react builder so I'm passing that as the this so I'm gonna say our builder like so now I can pass in that code without this our builder it wouldn't work I wouldn't be able to call div like I said I could pass our builder in here but then I'd be have did a little bit more typing not much more typing but just a little bit and also I don't want those warnings so I'm gonna grab this suppress warning thing and stick it up at the top so now you have the world's easiest less lease ceremony way of creating UI components what's more is you're doing so with a type safe language you get Auto completion refactoring this is pretty awesome huh this is this is so great this is the greatest thing since sliced bread alright yes oh sorry that was just a random Hamlet minute so over here now I'm just gonna say what game UI let's make sure everything still works as expected good alright adding on let's go to hand if you recall this is how you do CSS so let's add a little CSS here I'm gonna get rid of that and just do an export or import rather was it I can be my import option what cell alright so here I'm going to say let's see I'm gonna say width 10 point widths height same thing I'll give a padding of one front with I'll give it a see margin top and a margin right and I'll give it a background color of cyan cuz that's only four letters to spell all right let's see what that looks like here we go ah it's coming together coming together we have a nice blackjack game going on let's see I'm going to 11 I have 15 minutes left only holy smokes all right so now let's give it some let's give it some cards so we're gonna go in here and we're going to say cards let's see uh ah we don't have any data yet that would be useful remember I said I have a business model already created so let's go and grab that business model so here's the app that we're creating on the Left I already have this blackjack folder these are the business classes heart card deck game and hand I'll copy those and paste those into here now we have a business model so now what I'm going to do is I'm going to go to hand and I'm gonna say it takes an argument of type yeah cool so props react props are just arguments just parameter just phone some parameters you don't do anything special and I'm gonna go here and I'm gonna say H dot cards dot for each and I'll do a div for each card and I'll say plus it that's the current card that I'm entering through yes it doesn't have any specific support but with Kotlin it's pretty easy to make calls to external libraries and it's also easy for external libraries to make calls into Kotlin so it works without any special support alright so I'm gonna say card dot name so the card object has a name let's see how that looks that doesn't look good because we aren't actually passing in the hand yet haha all right so so hand now takes um hand UI takes a hand object so let's go into game guess what game is gonna take a game object so if you remember I have a game and a hand and so game has two properties one is player hand and one is dealer hand makes sense so game now requires a game to be passed to it so let's go up one level and let's do this here now this isn't necessarily how you would do it in production but we're gonna build on and we're gonna evolve this a little bit so I'm gonna say Val G equals game so I've instantiated game as a global object and I'm gonna pass it in right there good alright let's see if it works donut dough yes and if I hit refresh it should give me a whole new hands of course it's stuck at 12 points so let's fix that right no matter what it says twelve points and also it's stuck at player player so let's go now that we have data in hand this should probably be right we have H so this should be H dot name so a hand has a name and a hand also has a property called points good let's see how this works all right cool let's see we have 12 minutes to add some interactivity to it so what you've seen so far our reax function style components those are good for when all of the data necessary is passed in as an argument correct sooner or later somebody has to own the state for the UI is that makes sense in react it's a fairly common design pattern to push that up so that state management is up here does that make sense also if the events happened down here so let's say your UI is hierarchical state management is up here where do the events usually occur down here right so what happens is this guy throws an event up up up and then this guy handles the event way up here because he has the state to do so so in our case the state is just a game object so let's create a stateful or a class styled component this is a little bit more involved so we're gonna say new Kotlin class and I'll call this app this will be our top level component and with me it'll kind of reach so we're putting this in between index which is the top component now and game view this gonna be called app so class components or stateful components start out with a class and I'll just call it app and they extend our component so so far you've seen our builder anyplace you generate HTML you have to have our builder past as an argument as a receiver argument and stateful or class react components all have to extend our component and it's parameterised with a type representing the props and a type representing the state if you just do this then what you have is a component that doesn't have any profits or have any state make sense yes he asked if I could bump the font up all right so it's tell me I'm missing something so let's see what I'm missing obviously this component doesn't render anything so what's the one function that has to be there render so we'll use it or IntelliJ can't do that with JavaScript linear new since we're gonna be generating HTML from here it automatically is passing in our our receiver object so we can use the div and all those magic HTML tags so we'll start out real simple and we'll just say obviously not too useful so far correct but we're starting small we have on nine minutes left I think we're gonna make it so now I'm going to use app so for the moment I'm just gonna get rid of this so we've just gotten rid of everything we ever worked for ever but let's learn how to use an app so how to use an app so nor function components how do you use them they're just functions you just call the function right no reactive technology needed to use class components in in normal react there's also no special thing necessary because in react of course a class is a function right all right should say in JavaScript but they're not so in Kotlin so you have to do a little bit of extra stuff here so a little extra ceremony so there's a function called child I'm not sure why they call the child we're adding the child and so there you pass the app class object like so and also you pass any children in the form of a lambda function make sense so that's it so that's the special ceremony so if you have a class component you call it a little bit differently also in some of the examples what they do is they create a you could create a function a convenience function so that basically it looks exactly the same right so I could do that I could go like this and I could say app let's just go right here and say function app with lower case no args equals that while what am i doing No Oh that Oh oh yeah all right of course sorry all right so so that's a shortcut now all we have to do is go over here and say app so in that case it does look exactly like like the others so all right let's see if this works it's so far it should really just print out that yay all right now let's go back and let's actually put our game view in here so I'm gonna say game view or game UI and now we need some state actually let me put that on pause for a second and put that back we need some state so in real life you wouldn't use both of these like this so you're usually gonna have override this or override this so let's go and say interface app state and that's going to extend our state like so and I'm gonna say Val G game so I've just defined the shape of my state good now what I have to do is I have to initialize that state so I'm gonna override the init method like so you can also pass in props but we don't have any props in this case it automatically put that in there so that means do I need a prefix in order to reference G so instead of saying state G I just say G so I'm going to say G equals whoops oh this should be actually I'm gonna go there see that and of course then if I override that again what's gonna put here put the correct thing there we go alright so now I'm just say G equals new game like so let me make that a var instead of eval alright good now let's pass it in so now we actually can go back to using our game view their game UI and now I can pass in state dot G like so again we got Auto completion we get type safety and we should write be right back to what we had before let's go to index I think I want to get rid of the G over there so we don't want this global G anymore good and there's our app yay nothing different now the whole point of having a stateful class component is that you can actually change this date correct so for that we need a button so let's create some buttons any questions so far yes I'm using 8 I'm using 8 yeah I'm also using the latest EAP version of intelligent so now let's create a button bar here so let's just grab say this class I'm going f5 I'm gonna say button bar and I'm gonna say button so button is just like an HTML tag just like div and I'll say Plus deal so there's two three things you can do to change the state of a game you can deal which puts two new cards in each hand you can hit which adds one card to this guy's hand or you could do stay which basically starts adding cars to the dealer's hand until it gets to 17 you with me so deal hit stay I'll change the state of game so so there's how you do a button cool and let's put our button bar so I'm gonna say deal hit stay let's put our button bar in the UI so we'll go back to game view and put it right here um it does not need game you'll see in a second there's a kind of a special thing for that alright there's our button yay finally we want the buttons to actually do something so to make the buttons do something you go like this you say attributes remember we've seen that guy a couple times before whoops dot on click function equals and you give it a lambda and I'll say D for deal oh that's a lot of pressure but that guys getting a lot of applause all right so let's see if this runs it's right now just printing something to the console so I have to display the console yay all right um I do you guys want me to actually make the buttons change the game State that'll be approximately three more minutes all right if you hate my guts and are sick of this you leave you will not hurt my feelings but I'm gonna run three minutes over because this actually is kind of an important thing so the problem is I don't have a ability to access the game from here do i and the way we act works is you don't typically pass the state down what you do is you pass an event handler down so what I'm going to do is I'm going to say interface and I'm just going to call it event handler for lack of a better name and this interface is gonna have four things three things hit deal and stay that makes sense now what are these guys can actually do whoops so now what gets passed into this guy the callbacks right so now what they do is they say eh dot deal dot hit that's day like so good now we need to pass it down so that means game who's the parent he also needs one of those guys so I'm going to say eh and I'll say eh and he just passes it down to the button bar cool and finally the owner of the state is app state is a stateful component I now have a third guy and I'm gonna pass him in as an anonymous class so I'm gonna say object : eh and I'm an override three functions and now what they're going to do is they're gonna say set state which takes a lambda and in slips and inside a set state I'm going to say I'm going to say what gee deal so notice it's doing the set state asynchronously it's doing it in a in a lambda this will be d Gina hit and this will be stay and that's it let's see if it works Donna Noble you don't have to hit refresh but if you're too quick you do hit yes hit or miss Faye blue the stayed no I lost read heal and that is the end of my presentation thank you for coming please lab clap other than them [Applause]
Info
Channel: JetBrainsTV
Views: 30,484
Rating: undefined out of 5
Keywords: KotlinConf
Id: FDOECr-sT6U
Channel Id: undefined
Length: 47min 23sec (2843 seconds)
Published: Wed Nov 15 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.