yglf



yglf

0 0


yglf


On Github Gizra-Presentations / yglf

  • So what was it, Thursday, Friday
  • When we woke up to hear the world has changed.
  • Open the news on internet.
  • Seeing Cameron. Not this one, the sad one.
  • Resign from office.
  • And what was it, Friday or Saturday when there was this train accident in India with over 200 people dead.
  • And the Bituach Leumi. Which is the National insurance institute.
  • Very similar to the biblical story of Job. God and Satan had a bet.
  • I'm deviating, but I got a letter, as I get every year for the past 7 years.
  • Every year they tell me I have debt. Based on the fact that they think that I'm a stay home mom.
  • I'm willing to do everything. Everything to prove I'm not a mom.
  • And I could go on kids jump overy head. And traffic.
  • I guess the world we're leaving in, is probably the reason I love computers so much.
  • You start your day. Clean console. No surprises. You have full controll.
  • F*ck my like
gizra // @amitaibu
  • Past 7 years I have been a stay home mom, and/ or cto

Elm

A different approach to frontend webapps
  • My goal is to get you excited, and understand you can start using it today.
  • Build more easily, stable web apps
  • all JS frameworks have in common use JS
  • Agree or disagree, but JS is problematic
  • If JS ninja ok
  • JS is like getting root access to the server. You have too be very disiplined
  • Why we have in production: Pragmatic approach - Quickest, cheapest, solid, and keep devs moral
  • Bash Angular 1. Elm provides better tools to deal

Our evaluation process

  • Office timewatch
https://github.com/Gizra/elm-hedley
  • What helps us decide to transition from Angular, jump over react to Elm.
  • Typical webapp, login, github
  • Router
  • Maps
  • User interactions to filter events
https://github.com/Gizra/elm-spa-example
  • Nothing fancy, just login to GitHub, and fetch info.
  • But you can go ahead, after the presentation, and after reading the great Elm guide and learn how to build real apps.

Elm & Elm Architecture

  • Language: Compiled, Typed, Immutable, has no side effects, no run time errors
  • Set of best practices
  • Framework with its own language. It's very opininated
  • How to structure your application
  • How to connect components
  • Model -> Update -> View
  • Consists of a few prinicpels

Principle 1: Single source of truth

The state of your whole application is stored in a record tree
  • Saw first time it resonated with me
  • Redux taking inspiration from Elm
  • Angular 1 - where is your state? Router. Services.
  • Async nature of JS
  • Condition of your webapp
  • In case of bugs, hard to reproduce
  • Maybe counter intiutive (seperation of concerns) - control webapp

Principle 2: State is read-only

The only way to mutate the state is to emit an action describing what happened
  • It's 2016. The root of all evil in this worlds. heart worming, positive, non-cynical, world - 2 way data binding
  • Angular 1 site - Save me so many jQuery lines
  • What made us love it, is what we now hate
  • If view changes model, chain of actions. Can't control state
  • Next something that really got me existed. Ready? Ready?
module Counter exposing (..)

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onClick)

-- MODEL

type alias Model =
    Int

initialModel : Model
initialModel =
    0

init : ( Model, Cmd Msg )
init =
    ( initialModel
    , Cmd.none
    )

-- UPDATE

type Msg
    = Decrement
    | Increment


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
    case msg of
        Decrement ->
            ( model - 1
            , Cmd.none
            )

        Increment ->
            ( model + 1
            , Cmd.none
            )

-- VIEW

view : Model -> Html Msg
view model =
    div []
        [ button [ onClick Decrement ] [ text "-" ]
        , div [] [ text (toString model) ]
        , button [ onClick Increment ] [ text "+" ]
        ]

				
  • Eventhough syntax my look daunting
  • Boiler code, Show the essence
  • Msg: Angular1 - what actions can you do on your model?
  • When I click the button nothing will happen
  • Update is the brain of webapp, here we have logic

Model the problem

  • With elm, we can really start thinknig from the data structure level
  • Elm gives us powerfull tools to model our app
					
--

type alias User =
    { avatarUrl : String
    , name : String
    }

viewAvatar : String -> Html a
viewAvatar url =
    img [ src url ] []


--
					
				
  • This looks ok
					
--

type alias User =
    { avatarUrl : String
    , name : String
    }

viewAvatar : String -> Html a
viewAvatar url =
    img [ src url ] []


main = viewAvatar "But this isn't a URL!"
					
				
  • This looks ok

Compile Error Vs Runtime Mistakes

  • No Runtime errors in Elm
  • Shift as much runtime mistakes to compile time error

Types 101

					
type Bool = False | True
					
				
					
type UserType = Anonymous | Pending Integer | Authenticated String
					
				
  • User type can be either one.
  • Pending and Authenticated are wrapping a value.
					
--

type alias User =
    { avatarUrl : String
    , name : String
    }

viewAvatar : String -> Html a
viewAvatar url =
    img [ src url ] []


--
					
				
  • This looks ok
					
type Url = Url String

type alias User =
    { avatarUrl : Url
    , name : String
    }

viewAvatar : Url -> Html a
viewAvatar url =
    let
        (Url val) = url
    in
        img [ src val ] []
					
				
					
type Url = Url String

type alias User =
    { avatarUrl : Url
    , name : String
    }

viewAvatar : Url -> Html a
viewAvatar (Url val) =
    img [ src val ] []


--
					
				

Maybe values

					
type alias User =
    { avatarUrl : Url
    , name : String
    }

emptyUser =
    { avatarUrl = Url ""
    , name = ""
    }

type alias Model =
    { activePage : Page
    , user : User
    }

emptyModel =
    { activePage = Login
    , user = emptyUser
    }
					
				
  • Example without Maybe. But this is wrong.
					
type alias Model =
    { activePage : Page
    , user : Maybe User
    }

emptyModel =
    { activePage = Login
    , user = Nothing
    }

--
					
				
  • We know there is no User.
					

type alias Model =
    { activePage : Page
    , user : Maybe User
    }

emptyModel =
    { activePage = Login
    , user = Just { name = "Amitai"
                  , avatarUrl = "https://example.com/avatar"
                  }
    }
					
				
  • The use of "Just"

But we can do better

					
{-|
  * `NotAsked` - We haven't asked for the data yet.
  * `Loading` - We've asked, but haven't got an answer yet.
  * `Failure` - We asked, but something went wrong. Here's the error.
  * `Success` - Everything worked, and here's the data.
-}
type RemoteData e a
    = NotAsked
    | Loading
    | Failure e
    | Success a
					
				
					
type alias WebData a =
    RemoteData Http.Error a
					
				
					
type alias Model =
    { activePage : Page
    , user : WebData User
    }


emptyModel =
    { activePage = Login
    , user = NotAsked
    }
					
				
  • Using webdata, starting with NotAsked

Learn how to re-think with types

					
type Language
    = English
    | Spanish


type TranslationId
    = Login
    | WelcomeBack { name : String }


type alias TranslationSet =
    { english : String
    , spanish : String
    }


translations : TranslationId -> TranslationSet
translations id =
    case id of
        Login ->
            { english = "Please login"
            , spanish = "Por favor haga login"
            }

        WelcomeBack val ->
            { english = "Welcome back " ++ val.name
            , spanish = "Bienvenido " ++ val.name
            }


translate : Language -> TranslationId -> String
translate lang id =
    case lang of
        English ->
            .english <| translations id

        Spanish ->
            .spanish <| translations id

					
				
  • Using webdata, starting with NotAsked

Not everything is in Types

update : Msg -> Model -> Model
update msg model =
    case msg of
        Decrement ->
            model - 1





        Increment ->
            model + 1

				
update : Msg -> Model -> Model
update msg model =
    case msg of
        Decrement ->
            let
                newModel =
                    if model < 1 then 0 else model - 1
            in
                newModel

        Increment ->
            model + 1

				

Buisness Logic requires Testing

  • Who writes unit tests in JS?
  • Who enjoys it?
  • For the viewers at home, very few raised there hands, can't blame them
  • Probably the same amount of joy and happiness those guys in the back of Kim Jung Un must be feeling.
  • Probably the same amount of joy and happiness those guys in the back of Kim Jung Un must be feeling.

Unit tests

  • What makes unit tests easy Elm
  • Time to talk about "Pure functions and side effects"

Pure Functions & Side Effects

  • Elm is a black box with no connection to outside world
-- MODEL
type alias Model = Int

-- UPDATE
type Msg
 = Fetch
 | FetchSucceed Int
 | FetchFail Http.Error
         
  • Simple counter example, data from server
  • Action - nothing happens by itself
  • Code not compiled, for simplicity and brevity
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
 case msg of
   Fetch ->
     ( model
     , Task.perform FetchFail FetchSucceed (Http.get "https://api.example.com")
     )

   FetchSucceed count ->
     ( count, Cmd.none)

   FetchFail _ ->
     ( model, Cmd.none )

         
  • No HTTP happens.
  • Encourages us to be better developers

Yeoman Generator

https://github.com/Gizra/generator-elmlang
  • Gulp
  • browserSync
  • Auto-compile
  • Sass
  • Bundle and Deploy to gh-pages
  • Structured app
  • Travis integration
  • So, I read somewhere that a good presentation should end with a motif that was used in the beginning.
  • One of her quotes, and quite incredibly, I feel that it really encapsulats well this session.
  • I would kiss a frog even if there were no promise of a Prince Charming popping out of it. I love frogs. I'd lick him.
gizra | We are Hiring
So what was it, Thursday, Friday When we woke up to hear the world has changed. Open the news on internet.