$30 off During Our Annual Pro Sale. View Details »

JazzCon 2017: Building Web Apps with Elm Workshop

JazzCon 2017: Building Web Apps with Elm Workshop

Jeremy Fairbank

March 22, 2017
Tweet

More Decks by Jeremy Fairbank

Other Decks in Programming

Transcript

  1. @elpapapollo / jfairbank
    Building
    Web Apps with Elm
    Jeremy Fairbank
    Follow instructions here to get setup!
    github.com/jfairbank/elm-workshop

    View Slide

  2. Goals

    View Slide

  3. Goals
    • Benefits of Elm

    View Slide

  4. Goals
    • Benefits of Elm
    • Elm Syntax

    View Slide

  5. Goals
    • Benefits of Elm
    • Elm Syntax
    • Functional Programming

    View Slide

  6. Goals
    • Benefits of Elm
    • Elm Syntax
    • Functional Programming
    • Build web apps with Elm

    View Slide

  7. Format
    • Some slides.
    • Coding.
    • Ask questions!
    • Code along if you want.
    - Exercises

    View Slide

  8. Follow Along
    github.com/jfairbank/elm-workshop

    View Slide

  9. elm

    View Slide

  10. elm
    • Created in 2012 Evan Czaplicki

    View Slide

  11. elm
    • Created in 2012 Evan Czaplicki
    • Web and UI focused

    View Slide

  12. elm
    • Created in 2012 Evan Czaplicki
    • Web and UI focused
    • Compiles to JavaScript

    View Slide

  13. elm
    • Created in 2012 Evan Czaplicki
    • Web and UI focused
    • Compiles to JavaScript
    • Influences: Haskell, SML, OCaml, F#

    View Slide

  14. elm
    • Created in 2012 Evan Czaplicki
    • Web and UI focused
    • Compiles to JavaScript
    • Influences: Haskell, SML, OCaml, F#
    • Functional

    View Slide

  15. elm
    • Created in 2012 Evan Czaplicki
    • Web and UI focused
    • Compiles to JavaScript
    • Influences: Haskell, SML, OCaml, F#
    • Functional
    • Statically Typed

    View Slide

  16. What’s all the fuss about?

    View Slide

  17. undefined is not a function

    View Slide

  18. No runtime exceptions in
    practice.

    View Slide

  19. The argument to function `greet` is causing a mismatch.
    11| greet 42
    ^^
    Function `greet` is expecting the argument to be:
    String
    But it is:
    number
    Compile time static type checks

    View Slide

  20. Fast

    View Slide

  21. Fast

    View Slide

  22. Fast

    View Slide

  23. Functional

    View Slide

  24. Expressive and Declarative
    Concise and intent-revealing

    View Slide

  25. Expressive and Declarative
    Fewer lines of code!

    View Slide

  26. function doubleNumbers(numbers) {
    const doubled = [];
    const l = numbers.length;
    for (let i = 0; i < l; i++) {
    doubled.push(numbers[i] * 2);
    }
    return doubled;
    }
    doubleNumbers([1, 2, 3]);
    // [2, 4, 6]
    ×

    View Slide

  27. doubleNumbers list =
    List.map ((*) 2) list
    doubleNumbers myList -- [2, 4, 6]

    View Slide

  28. Pure Functions
    Predictable and easier to test

    View Slide

  29. add x y = x + y
    add 2 2 == 4
    add 2 2 == 4
    add 2 2 == 4

    View Slide

  30. Immutable Data
    No mutation bugs or inconsistent state

    View Slide

  31. × conference =
    { name = "JazzCon" }
    conference.name = "ConnectJS"

    View Slide

  32. conference =
    { name = "JazzCon" }
    nextConference =
    { conference | name = "ConnectJS" }

    View Slide

  33. Built-in Framework
    The Elm Architecture

    View Slide

  34. Built-in Framework
    Unidirectional with organized state
    changes

    View Slide

  35. Update
    View
    Model
    Messages

    View Slide

  36. Sold?
    Let’s learn Elm!

    View Slide

  37. Plan
    9:00 - 9:15 Intro
    9:15 - 9:45 Code: Syntax and Functional Programming
    9:45 - 9:55 The Elm Architecture
    9:55 - 10:30 Code: Building a Todo List
    10:30 - 11:00 Code: Exercise and Break
    11:00 - 11:10 HTTP: Commands and Decoders
    11:10 - 11:45 Code: Fetching a GitHub User
    11:45 - 12:00 Code: Exercise
    12:00 - 12:15 Code: Components
    12:15 - 12:30 Wrap Up

    View Slide

  38. Coding Time!
    Elm Syntax

    View Slide

  39. The Elm Architecture
    Model-View-Update

    View Slide

  40. Controller
    View
    Model
    Model
    Model
    Model
    Model
    View
    View
    View
    View
    MVC

    View Slide

  41. View
    Model
    Model
    Model
    Model
    Model
    View
    Model
    View
    Model
    View
    Model
    View
    Model
    Model
    Two-way Data Binding

    View Slide

  42. Update
    View
    Model
    Messages
    Unidirectional

    View Slide

  43. Update
    View
    Model
    Messages

    View Slide

  44. Model
    Single source of truth

    View Slide

  45. Model
    • String
    • Int
    • Record
    • List
    • Etc.
    Any data type

    View Slide

  46. Update
    View
    Model
    Messages

    View Slide

  47. View
    Projection of model

    View Slide

  48. UI as a Function
    Model
    Virtual
    DOM
    View

    View Slide

  49. elm
    Virtual
    DOM
    Todo List
    Learn Elm
    Build awesome Elm apps
    Learn functional programming

    View Slide

  50. Todo List
    Learn Elm
    Build awesome Elm apps
    Learn functional programming
    Model
    Delete first todo item

    View Slide

  51. View
    Model
    Notice missing item in virtual DOM list,
    so just remove corresponding .
    elm
    Virtual
    DOM
    Todo List
    Build awesome Elm apps
    Learn functional programming

    View Slide

  52. Update
    View
    Model
    Messages

    View Slide

  53. Messages
    Standardized application events

    View Slide

  54. elm
    app
    model

    View Slide

  55. elm
    app
    model
    Commands
    HTTP
    Dates
    Random #’s
    Subscriptions
    WebSockets
    Browser Window
    Mouse Position
    Events
    Text Input
    Mouse Click

    View Slide

  56. elm
    app
    model
    Commands
    HTTP
    Dates
    Random #’s
    Subscriptions
    WebSockets
    Browser Window
    Mouse Position
    Events
    Text Input
    Mouse Click

    View Slide

  57. Update
    View
    Model
    Messages

    View Slide

  58. Update
    Responds to messages
    and creates new state

    View Slide

  59. Update
    Model
    New
    Model Command

    View Slide

  60. model
    Update View
    elm

    View Slide

  61. model
    Update View
    elm

    View Slide

  62. model
    Update View
    elm

    View Slide

  63. model
    Update View
    elm
    !

    View Slide

  64. model
    Update View
    elm
    !

    View Slide

  65. model
    Update View
    elm

    View Slide

  66. model
    Update View
    elm

    View Slide

  67. model
    Update View
    elm

    View Slide

  68. model
    Update View
    elm

    View Slide

  69. Coding Time!
    Building a Todo List

    View Slide

  70. Exercise(s)
    • Allow adding new todo items.
    • Underneath todo list add a button to add a new todo item to the todo
    list.
    • The new todo item should have a blank description and should start off
    in an Editing state.
    • Hint: you’ll probably want the :: or ++ operators.
    • Allow deleting todo items.
    • Add delete button next to edit button.
    • Hint: editing/saving/completing required List.map. Deletion will
    require List.filter.
    • Allow marking a complete todo item as incomplete.

    View Slide

  71. Working with HTTP
    Commands and Decoders

    View Slide

  72. Update
    Model
    New
    Model Command

    View Slide

  73. Update
    Model
    New
    Model Command
    ?

    View Slide

  74. Side
    Effects
    I/O
    Mutable
    State

    View Slide

  75. Commands
    Describe side effects
    instead of doing them

    View Slide

  76. HTTP Commands
    Update
    Command elm

    View Slide

  77. What about the response?
    Update
    elm
    JSON

    View Slide

  78. What about the response?
    Update
    elm
    JSON
    Dynamic Payloads

    View Slide

  79. What about the response?
    Update
    elm
    JSON
    Dynamic Payloads
    Static Types

    View Slide

  80. Decoders
    Transform arbitrary JSON to
    static types

    View Slide

  81. user : User
    user =
    { id = 1
    , name = "Jeremy"
    }
    {
    "id": 1,
    "name": "Jeremy"
    }
    Decoder
    type alias User =
    { id : Int, name : String }

    View Slide

  82. {
    "id": 1
    }
    type alias User =
    { id : Int, name : String }
    Decoder
    ?

    View Slide

  83. {
    "id": 1
    }
    type alias User =
    { id : Int, name : String }
    Decoder
    ?

    View Slide

  84. {
    "id": 1
    }
    Decoder BadPayload
    Err

    View Slide

  85. {
    "id": 1
    }
    Decoder BadPayload
    Err
    Result type

    View Slide

  86. Result
    type Result error value
    = Ok value
    | Err error

    View Slide

  87. Result
    type Result error value
    = Ok value
    | Err error

    View Slide

  88. Result
    type Result error value
    = Ok value
    | Err error

    View Slide

  89. user =
    { id = 1
    , name = "Jeremy"
    }
    {
    "id": 1,
    "name": "Jeremy"
    }
    Decoder
    Ok

    View Slide

  90. {
    "id": 1,
    "name": "Jeremy"
    }
    “id”
    int
    “name”
    string

    View Slide

  91. {
    "id": 1,
    "name": "Jeremy"
    }
    “id”
    int
    “name”
    string
    Field decoders

    View Slide

  92. {
    "id": 1,
    "name": "Jeremy"
    }
    “id”
    int
    “name”
    string
    1
    Ok
    "Jeremy"
    Ok

    View Slide

  93. 1
    Ok
    "Jeremy"
    Ok
    User
    Decoder
    user =
    { id = 1
    , name = "Jeremy"
    }
    Ok

    View Slide

  94. 1
    Ok
    User
    Decoder
    BadPayload
    Err
    BadPayload
    Err

    View Slide

  95. Coding Time!
    Fetching a GitHub User

    View Slide

  96. Exercise(s)
    • Add a loading screen.
    • Display something like “Fetching user …”
    • Hint: what state should you update and when?
    • Display another field or two for the user.
    • Hint: Remember to update the User type and the userDecoder.
    • Decode GitHub error messages.
    • Use login nouser for testing.
    • Hint: you need to decode response.body in the Http.BadStatus
    branch.
    • Hint: you’ll probably want the decodeString and field functions from:

    package.elm-lang.org/packages/elm-lang/core/5.1.1/Json-Decode

    View Slide

  97. Coding Time!
    Components

    View Slide

  98. Components vs. Flat Structure

    View Slide

  99. Components vs. Flat Structure
    • Components
    • Pros
    • Perfect for independent,
    reusable applications
    • Single-page applications
    • Cons
    • Nested complexity
    • More boilerplate
    • Cumbersome parent-child
    communication

    View Slide

  100. Components vs. Flat Structure
    • Components
    • Pros
    • Perfect for independent,
    reusable applications
    • Single-page applications
    • Cons
    • Nested complexity
    • More boilerplate
    • Cumbersome parent-child
    communication
    • Flat Structure
    • Flatter state
    • Use function and module helpers
    • Pros
    • No parent-child
    communication ceremony
    • Easier to follow flow of
    application
    • Cons
    • Larger models
    • More Msg values

    View Slide

  101. Boilerplate
    But greater guarantees and safety

    View Slide

  102. Solving Boilerplate
    • github.com/halfzebra/create-elm-app
    • github.com/elm-community/elm-webpack-
    starter
    • github.com/gkubisa/elm-app-boilerplate
    • github.com/splodingsocks/elm-starter

    View Slide

  103. create-elm-app

    View Slide

  104. Tutorials
    • www.elm-tutorial.org
    • guide.elm-lang.org
    • frontendmasters.com/
    courses/elm/

    View Slide

  105. Elm in Action
    manning.com/books/elm-in-action

    View Slide

  106. Final Questions?

    View Slide

  107. @elpapapollo / jfairbank
    Thanks!
    Jeremy Fairbank
    Code:
    github.com/jfairbank/elm-workshop
    Slides:
    bit.ly/jazzcon17-elm-workshop

    View Slide