Skip to content

Instantly share code, notes, and snippets.

@urfolomeus
Last active September 22, 2015 15:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save urfolomeus/da694b3b06ed51c227ea to your computer and use it in GitHub Desktop.
Save urfolomeus/da694b3b06ed51c227ea to your computer and use it in GitHub Desktop.
module EffectsTest where
import Html exposing (..)
import Html.Events exposing (onClick)
import StartApp exposing (App)
import Task exposing (Task)
import Effects exposing (Effects, Never)
-- WIRING
app : App Model
app =
StartApp.start
{ init = initialModel "Hello"
, update = update
, view = view
, inputs = [incomingActions]
}
main : Signal Html
main =
app.html
port tasks : Signal (Task Never ())
port tasks =
app.tasks
-- MODEL
type alias Model = String
initialModel : String -> (Model, Effects Action)
initialModel string =
(string, Effects.none)
-- UPDATE
type Action = NoOp | RequestString | Write Model
update : Action -> Model -> (Model, Effects Action)
update action model =
case action of
NoOp ->
(model, Effects.none)
RequestString ->
(model, getNewString)
Write string ->
(string, Effects.none)
-- VIEW
view : Signal.Address Action -> Model -> Html
view address model =
div [ ]
[ text model
, button
[ onClick address RequestString ]
[ text "Click me!" ]
]
-- PORTS
port incoming : Signal Model
port outgoing : Signal String
port outgoing =
outbox.signal
-- SIGNALS
incomingActions : Signal Action
incomingActions =
Signal.map (\string -> Write string) incoming
outbox : Signal.Mailbox String
outbox =
Signal.mailbox ""
-- EFFECTS
getNewString : Effects Action
getNewString =
Signal.send outbox.address ""
|> Effects.task
|> Effects.map (always NoOp)
<!DOCTYPE html>
<html>
<head>
<title>Effects Test</title>
<script src="elm.js"></script>
</head>
<body>
<div id="elmMain"></div>
</body>
<script>
var elmDiv = document.getElementById('elmMain')
, elmApp = Elm.embed(Elm.EffectsTest, elmDiv, {incoming: ""});
elmApp.ports.incoming.send("Hello from outside");
elmApp.ports.outgoing.subscribe(function () {
elmApp.ports.incoming.send("You rang?");
});
</script>
</html>
@urfolomeus
Copy link
Author

TL;DR
How do I deal with an Effect that needs to perform a Task but does not have an affect on the model?

I'm trying to create a basic Elm application that does the following:

  1. Accepts values from JavaScript on the incoming port, calls the Write Action in the update function and writes the given value to the View. This part works fine.
  2. Sends a message to JavaScript over the outgoing port to ask it to send a different String to the incoming port thus triggering step 1. This is the part where I am stuck.

I have a working solution that does not use Effects, but I want to be able to use StartApp so I need to work with Effects. The issue, I believe, is down to the fact that an Effect expects to have an affect on the application via a Task sent back to the update function. However I have no need to do anything as getNewString merely asks the outside world to do something. It does not wait for the response.

So, can I send back a NoOp Effect somehow? Is there a better way of doing this?

@urfolomeus
Copy link
Author

@jessitron replied with

Signal.send outbox.address ""
  |> Effects.task
  |> Effects.map (\_ -> NoOp)

@urfolomeus
Copy link
Author

@mgold pointed out that (\_ -> ...) is such a common pattern in Elm that there is a more common way to do it (always ...)

@urfolomeus
Copy link
Author

Updated to show the final solution :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment