Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Full-Stack app with Kotlin —by an Android De...

A Full-Stack app with Kotlin —by an Android Developer

This was presented at BlrKotlin Meetup.

Bedanta Bikash Borah

March 10, 2018
Tweet

More Decks by Bedanta Bikash Borah

Other Decks in Technology

Transcript

  1. What are we building ? Ktor Backend React-Kotlin App Email

    Id Slack channel name Secret key Status Email Id Status Code
  2. ‣ Basic HTML ‣ Basic CSS ‣ Optional ReactJs or

    React Native ‣ Basic Kotlin ‣ Familiarity with Gradle. Prerequisite
  3. ‣ Develop Backend (Ktor). ‣ Deploy Backend on Heroku. ‣

    Develop Frontend. (React-Kotlin App) ‣ Deploy Frontend on Heroku. Steps
  4. Build.gradle dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" testCompile group: 'junit', name: 'junit',

    version: '4.12' + compile "org.jetbrains.ktor:ktor-core:$ktor_version" + compile "org.jetbrains.ktor:ktor-netty:$ktor_version" }
  5. application.conf ktor { deployment { environment = development port =

    ${PORT} } application { modules = [ MainClassKt.main ] } }
  6. MainClass.kt fun Application.main() { install(CORS){ anyHost() } install(DefaultHeaders) install(Routing) {

    get("") { call.respondText("Hello World", ContentType.Text.JavaScript) } post("/invite_post/") {- - -} } }
  7. post("/invite_post/") { val vm = call.request.receive<ValuesMap>() val url = "https://$slackName.slack.com/api/users.admin.invite"

    val payload = mapOf("token" to slackToken, "email" to vm.get("email")) val r = post(url, data = payload) if (r.jsonObject.getBoolean("ok")) { call.respondText("{\"status\":1}", ContentType.Text.JavaScript) } else { when(r.jsonObject.getString("error")){ "already_invited" -> call.respondText("{\"status\":2}", ContentType.JavaScript) } } MainClass.kt
  8. Serving JSON + compile “com.google.code.gson:gson:X.X.X” data class Response(val status: String,

    val error: String) val response = Response(“not-ok”, “bad params”) val gson = Gson() val json = gson.toJson(response) call.respondText(json, ContentType.Application.Json)
  9. Install Heroku Mac brew install heroku Ubuntu wget -qO- https://cli-assets.heroku.com/install-ubuntu.sh

    | sh Windows Download Installer from https://devcenter.heroku.com/articles/heroku-cli
  10. Building the Deployment Jar task deployJar(type: Jar) { manifest {

    attributes "Implementation-Title": "gradle-jar-file", 'Implementation-Version': 1.0, 'Main-Class': 'org.jetbrains.ktor.netty.DevelopmentHost' } baseName = project.name + '-all' from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar }
  11. npm install -g create-react-kotlin-app create-react-kotlin-app yourApp cd yourApp/ npm start

    Then open http://localhost:3000/ to see your app. Creating React App
  12. my-app/ README.md node_modules/ package.json .gitignore public/ favicon.ico index.html manifest.json src/

    app/ App.css App.kt index/ index.css index.kt logo/ kotlin.svg Logo.css Logo.kt react.svg ticker/ Ticker.kt Project Structure
  13. my-app/ README.md node_modules/ package.json .gitignore public/ favicon.ico index.html manifest.json src/

    app/ App.css App.kt UiState.kt index/ index.css index.kt ui/ fullUi.Kt inputUi.kt Project Structure
  14. UiState.kt data class UiState( var heading: String, var placeholder: String,

    var buttonText: String, var isInviteSent:Boolean, var email: String)
  15. App.kt interface AppUiState : RState { var uiState: UiState }

    class App : RComponent<RProps, AppUiState>() { override fun AppUiState.init() { uiState = UiState( "Get Invite to BlrKotlin Slack Channel", "[email protected]", "Get an Invite", false, "") } override fun RBuilder.render() { fullui(state.uiState, object : EventHandler { override fun emailChanged(email: String) {} override fun submitClicked() {} }) } private fun parse(json: dynamic): Int { return json.status } } fun RBuilder.app() = child(App::class) { }
  16. inputUi.kt interface EventHandler { fun submitClicked() fun emailChanged(email: String) }

    fun RBuilder.inputUi(state: UiState, eventHandler: EventHandler) { var email ="" div { input(type = InputType.email, name = "itemText") { attrs { placeholder = state.placeholder onChangeFunction = { val target = it.target as HTMLInputElement eventHandler.emailChanged(target.value) } } } button { attrs.text(state.buttonText) attrs.disabled = state.isInviteSent attrs.onClickFunction = { eventHandler.submitClicked() } } } }
  17. App.kt override fun emailChanged(email: String) { setState { state.uiState.email =

    email } } override fun submitClicked() { if(state.uiState.email.isEmpty()){ //Show an error message maybe. return } window.fetch(url, object : RequestInit { override var method: String? = "POST" override var body: dynamic = URLSearchParams().apply { append("email", "${state.uiState.email}") } }).then { response -> response.json().then({ resolve -> when (parse(resolve)) { 1 -> { setState { state.uiState.isInviteSent = true state.uiState.buttonText = "Check your Email" } } }, { t -> console.log(t) }) } }
  18. git push heroku master heroku open Your App will open

    in your default Browser. Configure Heroku