Skip to content

Instantly share code, notes, and snippets.

@MangelMaxime
Last active June 26, 2019 19:32
Show Gist options
  • Save MangelMaxime/a5488a7bd45c49659c12e5158024180d to your computer and use it in GitHub Desktop.
Save MangelMaxime/a5488a7bd45c49659c12e5158024180d to your computer and use it in GitHub Desktop.
Showcase throttle on input from view
html,
body {
font-size: 16px;
}
.main-container {
display: flex;
width: 100%;
height: 100%;
justify-content: center;
align-items: center;
flex-direction: column;
}
.input {
padding: .25rem;
font-size: 16px;
width: 250px;
margin-bottom: 1rem;
}
module Thoth.RandomUser
(**
Small application showing how to use:
- Thoth.Json (https://mangelmaxime.github.io/Thoth/json/v3.html)
- Promise and Fetch APIs
*)
open System
open Fable.Core
open Fable.Core.JsInterop
open Fable.React
open Fable.React.Props
open Browser
open Elmish
open Elmish.React
open Thoth.Json
// The implementation is in pure JS because I already had it ready
// See the HTML tab
let throttle (callback : 'arg -> unit) wait (immediate : bool) : 'arg -> unit =
window?throttle(callback, wait, immediate)
type Model =
{ ThrottleValue : string }
type Msg =
| ThrottleValue of string
/// At first, we have no user to display
let init () =
{ ThrottleValue = "" }, Cmd.none
// UPDATE
let update (msg:Msg) (model:Model) =
match msg with
| ThrottleValue value ->
JS.console.log("Throttle value received: ", value)
{ model with
ThrottleValue = value
}
, Cmd.none
// VIEW (rendered with React)
type Props =
{ Model : Model
Dispatch : Dispatch<Msg> }
let throttleView =
FunctionComponent.Of(fun (props : Props) ->
let onChange =
Hooks.useRef(
throttle
(fun (value : string) ->
value
|> ThrottleValue
|> props.Dispatch
)
300
false
).current
div [ Class "main-container" ]
[ span [ ]
[ str "See how the 'echoed' string have a sligh delay compared to the input" ]
input [ Class "input"
DefaultValue props.Model.ThrottleValue
// RefValue selfRef
OnChange (fun ev ->
onChange ev?target?value
)
]
span [ ]
[ str "Hello, "
str props.Model.ThrottleValue
str "!" ] ]
, "throttleView"
,equalsButFunctions)
let view model dispatch =
div [ Class "main-container" ]
[ throttleView
{ Model = model
Dispatch = dispatch } ]
// App
Program.mkProgram init update view
|> Program.withReactSynchronous "elmish-app"
|> Program.run
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<script src="__HOST__/libs/react.production.min.js"></script>
<script src="__HOST__/libs/react-dom.production.min.js"></script>
<link rel="stylesheet" href="__HOST__/libs/css/bulma.min.css" />
<link rel="stylesheet" href="__HOST__/libs/css/all.min.css" />
</head>
<body class="app-container">
<script type="text/javascript">
window.throttle = function (callback, wait, immediate) {
let timeout = null
let initialCall = true
return function () {
const callNow = immediate && initialCall
const next = () => {
callback.apply(this, arguments)
timeout = null
}
if (callNow) {
initialCall = false
next()
}
if (!timeout) {
timeout = setTimeout(next, wait)
}
}
}
</script>
<div id="elmish-app" class="elmish-app"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment