Skip to content

Instantly share code, notes, and snippets.

@iamvery
Last active July 11, 2017 15:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save iamvery/0ac82fd93a110452bc035b2d84809c19 to your computer and use it in GitHub Desktop.
Save iamvery/0ac82fd93a110452bc035b2d84809c19 to your computer and use it in GitHub Desktop.
Elm with a React head, cause why not?
  1. Build chat JS with elm-make Chat.elm --output=chat.js.
  2. Run local webserver, maybe ruby -run -e httpd -- -p 5000 .
port module Chat exposing (main)
-- https://github.com/elm-lang/core/issues/703
import Json.Decode
import WebSocket
port messages : List String -> Cmd msg
port input : (String -> msg) -> Sub msg
port submit : (String -> msg) -> Sub msg
type alias Model =
{ input : String, messages : List String }
type Msg
= Input String
| Send String
| NewMessage String
init : ( Model, Cmd msg )
init =
( { input = "", messages = [] }, Cmd.none )
update : Msg -> Model -> ( Model, Cmd msg )
update msg model =
case msg of
Input input ->
( { model | input = input }, Cmd.none )
Send _ ->
( model, WebSocket.send "ws://echo.websocket.org" model.input )
NewMessage str ->
( { model | messages = str :: model.messages }, messages (str :: model.messages) )
subscriptions : Model -> Sub Msg
subscriptions _ =
Sub.batch
[ input Input
, submit Send
, WebSocket.listen "ws://echo.websocket.org" NewMessage
]
main : Program Never Model Msg
main =
Platform.program { init = init, update = update, subscriptions = subscriptions }
<html>
<head></head>
<body>
<main id="root"></main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.js"></script>
<script src="./chat.js"></script>
<script>
let app = Elm.Chat.worker();
let onSubmit = (e) => {
e.preventDefault()
e.target.reset()
app.ports.submit.send('')
}
let onInput = (e) => {
app.ports.input.send(e.target.value)
}
let view = ({messages}) => React.createElement('div', null,
React.createElement('form', {onSubmit}, React.createElement('input', {onInput})),
React.createElement('ul', null,
messages.map((message) => React.createElement('li', null, message)),
),
)
class App extends React.Component {
constructor() {
super()
this.state = {messages: []}
}
componentDidMount() {
app.ports.messages.subscribe(messages => this.setState({messages}))
}
render() {
return React.createElement(view, {messages: this.state.messages})
}
}
ReactDOM.render(
React.createElement(App),
document.getElementById('root'),
)
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment