Slide 1

Slide 1 text

/ @jossiwolf

Slide 2

Slide 2 text

Jossi Wolf Android Developer High School Student @jossiwolf

Slide 3

Slide 3 text

AGENDA - INTRODUCTION - WHY KOTLIN? - GETTING STARTED - DIFFERENCES - USING NODEJS - CREATING A WEBSITE - CONCLUSION @jossiwolf

Slide 4

Slide 4 text

/ @jossiwolf

Slide 5

Slide 5 text

WHY KOTLIN? THE CASE AGAINST JAVASCRIPT @jossiwolf

Slide 6

Slide 6 text

STATICALLY TYPED DYNAMICALLY TYPED var hello = "Hello" hello = 5 ❌ let hello = "Hello" hello = 5 ✅ @jossiwolf

Slide 7

Slide 7 text

DEVELOPER HAPPINESS IS IMPORTANT! @jossiwolf

Slide 8

Slide 8 text

INTEROPERABILITY @jossiwolf

Slide 9

Slide 9 text

SCALABILITY @jossiwolf

Slide 10

Slide 10 text

CODE REUSE @jossiwolf

Slide 11

Slide 11 text

DIFFERENCES @jossiwolf

Slide 12

Slide 12 text

PACKAGE NAMES IN FILES ARE OPTIONAL @jossiwolf

Slide 13

Slide 13 text

NO JAVA APIs @jossiwolf

Slide 14

Slide 14 text

GETTING STARTED @jossiwolf

Slide 15

Slide 15 text

@jossiwolf

Slide 16

Slide 16 text

@jossiwolf

Slide 17

Slide 17 text

2. Wait for Gradle build to finish (⏳) @jossiwolf

Slide 18

Slide 18 text

@jossiwolf

Slide 19

Slide 19 text

buildscript { ext.kotlin_version = '1.2.10' repositories { mavenCentral() } dependencies { classpath "$kotlin_gradle_plugin:$kotlin_version" } } apply plugin: 'kotlin-js' repositories { mavenCentral() } dependencies { compile "$kotlin_stdlib_js:$kotlin_version" } @jossiwolf

Slide 20

Slide 20 text

compileKotlin2Js.kotlinOptions { sourceMap = true //Generate a source-map for debug } @jossiwolf

Slide 21

Slide 21 text

compileKotlin2Js.kotlinOptions { sourceMap = true //Generate a source-map for debug sourceMapEmbedSources = "always" //And embed the source } @jossiwolf

Slide 22

Slide 22 text

compileKotlin2Js.kotlinOptions { sourceMap = true //Generate a source-map for debug sourceMapEmbedSources = "always" //And embed the source moduleKind = "plain" //The module loader to be used } @jossiwolf

Slide 23

Slide 23 text

compileKotlin2Js.kotlinOptions { sourceMap = true //Generate a source-map for debug sourceMapEmbedSources = "always" //And embed the source moduleKind = "plain" //The module loader to be used outputFile = "web/index.js" //Output file that we use } @jossiwolf

Slide 24

Slide 24 text

USING NODE.JS @jossiwolf

Slide 25

Slide 25 text

compileKotlin2Js.kotlinOptions { moduleKind = "commonjs" } @jossiwolf

Slide 26

Slide 26 text

fun main(args: Array) { console.log("Hello from Kotlin!") } @jossiwolf

Slide 27

Slide 27 text

$ gradle build @jossiwolf

Slide 28

Slide 28 text

$ gradle build $ node node/index.js @jossiwolf

Slide 29

Slide 29 text

$ gradle build $ node node/index.js > Hello from Kotlin! @jossiwolf

Slide 30

Slide 30 text

dynamic //„Disables“ type-safety @jossiwolf

Slide 31

Slide 31 text

dynamic //„Disables“ type-safety val hello: dynamic = "Hello" hello.whatever() hello.itDoesntMatter @jossiwolf

Slide 32

Slide 32 text

external //This is defined externally @jossiwolf

Slide 33

Slide 33 text

external fun require(module: String): dynamic @jossiwolf

Slide 34

Slide 34 text

INTERACTING WITH THE DOM @jossiwolf

Slide 35

Slide 35 text

task assembleWeb(type: Sync) { configurations.compile.each { File file -> from(zipTree(file.absolutePath), { includeEmptyDirs = false include { fileTreeElement -> def path = fileTreeElement.path path.endsWith(".js") && (path.startsWith("META-INF/resources/") || !path.startsWith("META-INF/")) } }) } from compileKotlin2Js.destinationDir into "${projectDir}/web" dependsOn classes } assemble.dependsOn assembleWeb @jossiwolf

Slide 36

Slide 36 text

document#getElementById @jossiwolf

Slide 37

Slide 37 text

document#getElementById document#getElementsByClassName @jossiwolf

Slide 38

Slide 38 text

document#getElementById document#getElementsByClassName // All the normally available @jossiwolf

Slide 39

Slide 39 text

div { } @jossiwolf

Slide 40

Slide 40 text

div { h1 { +"This is some text from Kotlin!" } } @jossiwolf

Slide 41

Slide 41 text

document.body?.append { div { h1 { +"This is some text from Kotlin!" } } } @jossiwolf

Slide 42

Slide 42 text

Kotlin & JS <3 @jossiwolf

Slide 43

Slide 43 text

@jossiwolf

Slide 44

Slide 44 text

@jossiwolf

Slide 45

Slide 45 text

Title goes here

Subtitle here

Some text goes here Action 1 Action 2
@jossiwolf

Slide 46

Slide 46 text

DSL (DOMAIN SPECIFIC LANGUAGE) „BUILDERS ON STEROIDS“ @jossiwolf

Slide 47

Slide 47 text

verticalLayout { val name = editText() button("Say Hello") { onClick { toast("Hello, ${name.text}!") } } } @jossiwolf

Slide 48

Slide 48 text

div("mdc-card") { section("mdc-card__primary") { h1("mdc-card__title) { +"This is the title" } h2("mdc-card__subtitle") { +"Subtitle" } } section("mdc-card__supporting-text") { +"This is the card's text" } } @jossiwolf

Slide 49

Slide 49 text

fun DIV.card(title: String, subtitle: String, text: String) { div("mdc-card") { section("mdc-card__primary") { h1("mdc-card__title") { +title } h2("mdc-card__subtitle") { +subtitle } } section("mdc-card__supporting-text") { +text } } } @jossiwolf

Slide 50

Slide 50 text

fun DIV.card(title: String, subtitle: String, text: String) { div("mdc-card") { section("mdc-card__primary") { h1("mdc-card__title") { +title } h2("mdc-card__subtitle") { +subtitle } } section("mdc-card__supporting-text") { +text } } } @jossiwolf

Slide 51

Slide 51 text

document.create.div { card("Card Title", "Card Subtitle", "Card Text") } @jossiwolf

Slide 52

Slide 52 text

@jossiwolf

Slide 53

Slide 53 text

card { title = "Card Title" subtitle = "Card Subtitle" text = "Hello Kotlin Meetup!„ } @jossiwolf

Slide 54

Slide 54 text

card { title = "Card Title" subtitle = "Card Subtitle" text = "Hello Kotlin Meetup!" action { text = "Action!" } elevation = 6 } @jossiwolf

Slide 55

Slide 55 text

HIGHER-ORDER FUNCTIONS @jossiwolf

Slide 56

Slide 56 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } @jossiwolf

Slide 57

Slide 57 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } The function takes a string as parameter @jossiwolf

Slide 58

Slide 58 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } The function takes a string as parameter @jossiwolf

Slide 59

Slide 59 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } The function takes a string as parameter Its return type is also String @jossiwolf

Slide 60

Slide 60 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } println(higherOrderFunction { it }) //Prints „Hello from up here“ The function takes a String as parameter Its return type is Also String @jossiwolf

Slide 61

Slide 61 text

fun higherOrderFunction(block: (String) -> String): String { return block("Hello from up here") } println(higherOrderFunction { return@higherOrderFunction it }) //Prints „Hello from up here“ The function takes a String as parameter Its return type is Also String @jossiwolf

Slide 62

Slide 62 text

RECEIVERS @jossiwolf

Slide 63

Slide 63 text

card { title = "Card Title" subtitle = "Card Subtitle" text = "Hello Kotlin Meetup!" } @jossiwolf

Slide 64

Slide 64 text

class MaterialCardOptions { lateinit var title: String lateinit var subtitle: String lateinit var text: String } @jossiwolf

Slide 65

Slide 65 text

fun card(block: MaterialCardOptions.() -> Unit) { val options = MaterialCardOptions().apply(block) println(JSON.stringify(options)) } @jossiwolf

Slide 66

Slide 66 text

fun card(block: MaterialCardOptions.() -> Unit) { val options = MaterialCardOptions().apply(block) println(JSON.stringify(options)) } @jossiwolf

Slide 67

Slide 67 text

card { title = "Hello" subtitle = "Subtitle" } @jossiwolf

Slide 68

Slide 68 text

card { title = "Hello" subtitle = "Subtitle" } { "title_xesk5l$_0": "Hello", "subtitle_x7q17f$_0": "Subtitle", "actions": [] } @jossiwolf

Slide 69

Slide 69 text

document.body?.append { div { } } @jossiwolf

Slide 70

Slide 70 text

fun DIV.card(block: MaterialCardOptions.() -> Unit) { val options = MaterialCardOptions().apply(block) div("mdc-card") { section("mdc-card__primary") { h1 { classes = setOf("mdc-card__title") +options.title } h2("mdc-card__subtitle") { +options.subtitle } } section("mdc-card__supporting-text") { +options.text } } } @jossiwolf

Slide 71

Slide 71 text

document.body?.append { div { card { title = "Shiba Inu" subtitle = "Japanese Dog Breed" text = "Shiba Inu, also known as Doge, is a Japanese dog breed." } } } @jossiwolf

Slide 72

Slide 72 text

SHOULD I USE IT? (IN PRODUCTION) @jossiwolf

Slide 73

Slide 73 text

NOT REALLY. @jossiwolf

Slide 74

Slide 74 text

medium.com/@jossiwolf twitter.com/jossiwolf github.com/jossiwolf speakerdeck.com/jossiwolf