Skip to content

Instantly share code, notes, and snippets.

@mrmurphy
Created November 26, 2015 18:00
Show Gist options
  • Save mrmurphy/590f214dc15eae0bcfb6 to your computer and use it in GitHub Desktop.
Save mrmurphy/590f214dc15eae0bcfb6 to your computer and use it in GitHub Desktop.
Homespunn Elm Router using the Elm application architecture
module Main where
import StartApp as StartApp
import Task
import Effects exposing (Never, Effects)
import History
import Signal
import Html exposing (Html, text)
import Debug
import Time
import Login as Login
import Home as Home
-- -- Router
-- Model
type Action
= UpdateCurrentPath String
| Home Home.Action
| Login Login.Action
| NoOp
type alias Model =
{ path: String,
home: Home.Model,
login: Login.Model
}
init : (Model, Effects Action)
init =
let
(homeModel, homeEffects) = Home.init
(loginModel, loginEffects) = Login.init
in
( { path = "init"
, home = homeModel
, login = loginModel
}
, Effects.batch
[ notifyLoad
, (Effects.map Home homeEffects)
, (Effects.map Login loginEffects)
]
)
-- Update
update : Action -> Model -> (Model, Effects Action)
update action model =
let
action = Debug.log "Action coming through" action
in
case action of
UpdateCurrentPath newPath -> ({model | path = newPath}, Effects.none)
Home subAction ->
let
(subModel, subEffects) = (Home.update subAction model.home)
in
( {model | home = subModel}
, Effects.map Home subEffects
)
Login subAction ->
let
(subModel, subEffects) = (Login.update subAction model.login)
in
( {model | login = subModel}
, Effects.map Login subEffects
)
NoOp -> (model, Effects.none)
-- View
view : Signal.Address Action -> Model -> Html
view address model =
let
routeOn = model.path
in
case routeOn of
"init" -> (text <| "")
"/admin" -> Home.view (Signal.forwardTo address Home) model.home
"/login" -> Login.view (Signal.forwardTo address Login) model.login
_ -> (text <| "404, not found!" ++ model.path)
-- -- End Router
routeChanges : Signal Action
routeChanges =
Signal.map UpdateCurrentPath History.path |>
Signal.map (Debug.log "path change")
app =
StartApp.start
{ init = init
, update = update
, view = view
, inputs = [pathSignalThatUpdatesOnInit]
}
main =
app.html
port tasks : Signal (Task.Task Never ())
port tasks =
app.tasks
initBox : Signal.Mailbox ()
initBox =
Signal.mailbox ()
notifyLoad : Effects Action
notifyLoad =
(Effects.task <<
Task.map (always NoOp))
(Signal.send initBox.address ())
pathSignalThatUpdatesOnInit : Signal Action
pathSignalThatUpdatesOnInit =
Signal.merge routeChanges <|
Signal.sampleOn initBox.signal routeChanges
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment