0
\$\begingroup\$

This code is a working example of an Elm application (0.19.1) that is spread over two files. The idea is to have a file for each page of the app and have the Main.elm file import and connect the pages (exactly the same idea as the elm spa example)

This is a bare bones example, that I intend to build upon for my own use case. In creating this I really struggled with interpreting and writing correct type annotations.

I'd like to get feedback on places where I haven't followed standard Elm idioms or have named variables poorly or have incorrectly used camelCase. Really any feedback that would improve my code would be appreciated.

I'm new to Elm and want to get off to the right start before I go ahead and create a code mess.

Compiled output (Html document) here

Main.elm

module Main exposing (..)

import Browser
import Home
import Html exposing (..)

main =
    Browser.element
        { init = init
        , subscriptions = subscriptions
        , update = update
        , view = view
        }

type Model
    = HomeModel Home.Model
    | Login

type Msg
    = HomeMsg Home.Msg


init : () -> ( Model, Cmd msg )
init _ =
    let
        mapModel : a -> (a -> Model) -> Model
        mapModel model toModel =
            toModel model
    in
    ( mapModel (Home.defaultModel Nothing) HomeModel, Cmd.none )


update: Msg -> Model -> (Model, Cmd msg)
update msg model =

    let
        mapModel : (m, Cmd msg) -> (m -> Model) -> (Model, Cmd msg)
        mapModel (m, c) toModel =
            (toModel m, c)
    in
    case (msg, model) of
        (HomeMsg homeMsg, HomeModel homeModel)->
            mapModel (Home.update homeMsg homeModel) HomeModel
        (_, _) ->
            (model, Cmd.none)


view: Model -> (Html Msg)
view model =
    case model of
        HomeModel homeModel ->
            Html.map HomeMsg (Home.view homeModel)
        _ ->
            div [][text "Op's you found a hole"]


subscriptions : Model -> Sub msg
subscriptions model =
    Sub.none

Home.elm

module Home exposing (..)
import Element as El exposing (..)
import Element.Input as In
import Html exposing (Html)


type alias Model =
    { input : String
    }

defaultModel: Maybe String -> Model
defaultModel maybeInput =
    case maybeInput of
        Just input ->
            Model input
        Nothing ->
            Model ""


type Msg
    = UpdateString String


view : Model -> Html Msg
view model =
    El.layout []
        (el []
            (row []
                [ el [] (El.text "Welcome") -- header
                , In.text []
                    { onChange = \x -> UpdateString x
                    , text = model.input
                    , placeholder = Nothing
                    , label = In.labelBelow [] (text "Hello world")
                    }
                ]
            )
        )


update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
    case msg of
        UpdateString input ->
            ( { model | input = input }, Cmd.none)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.