on develop help sign in
Merge pull request #287 from reflex-frp/aa-formdata

Add module for building and posting XHR FormData requests

commitaa52102cc6a610e5554bb3e902c6017d4faad894 authorRyan Trinkle <ryan.trinkle@gmail.com> dateFri 8 Mar 2019, 10:29 (8 years ago) parenta851884f740652
3 files changed+49
reflex-dom-core/reflex-dom-core.cabal+1 reflex-dom-core/src/Reflex/Dom/Core.hs+1 reflex-dom-core/src/Reflex/Dom/Xhr/FormData.hs+47
reflex-dom-core/reflex-dom-core.cabal+1
@@ -110,6 +110,7 @@ library
110110 Reflex.Dom.Widget.Lazy
111111 Reflex.Dom.Widget.Resize
112112 Reflex.Dom.Xhr
113+ Reflex.Dom.Xhr.FormData
113114 other-modules:
114115 Foreign.JavaScript.Internal.Utils
115116 Reflex.Dom.WebSocket.Foreign
reflex-dom-core/src/Reflex/Dom/Core.hs+1
@@ -18,3 +18,4 @@ import Reflex.Dom.Prerender as X
1818import Reflex.Dom.WebSocket as X
1919import Reflex.Dom.Widget as X
2020import Reflex.Dom.Xhr as X
21+import Reflex.Dom.Xhr.FormData as X
reflex-dom-core/src/Reflex/Dom/Xhr/FormData.hsnew file+47
@@ -0,0 +1,47 @@
1+{-# LANGUAGE FlexibleContexts #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+module Reflex.Dom.Xhr.FormData
4+ ( postForms
5+ , FormValue (..)
6+ , fileToFormValue
7+ )
8+ where
9+
10+import Control.Lens
11+import Data.Default
12+import Data.Map (Map)
13+import Data.Text (Text)
14+import Data.Traversable
15+import qualified GHCJS.DOM.FormData as FD
16+import Foreign.JavaScript.TH
17+import GHCJS.DOM.File (getName)
18+import GHCJS.DOM.Types (File, IsBlob)
19+import Language.Javascript.JSaddle.Monad (MonadJSM, liftJSM)
20+import Reflex
21+import Reflex.Dom.Xhr
22+
23+-- | A FormData value may be a blob/file or a string. The file can optionally be provided with filename.
24+data FormValue blob = FormValue_Text Text
25+ | FormValue_File blob (Maybe Text) -- maybe filename
26+
27+-- | Performs a POST request with the provided FormData payload
28+postForms
29+ :: ( IsBlob blob, HasJSContext (Performable m), MonadJSM (Performable m)
30+ , PerformEvent t m, TriggerEvent t m
31+ , Traversable f)
32+ => Text -- ^ The target url
33+ -> Event t (f (Map Text (FormValue blob))) -- ^ Maps of text keys and values that will be sent as "FormData"
34+ -> m (Event t (f XhrResponse))
35+postForms url payload = do
36+ performMkRequestsAsync $ ffor payload $ \fs -> for fs $ \u -> liftJSM $ do
37+ fd <- FD.newFormData Nothing
38+ iforM_ u $ \k v -> case v of
39+ FormValue_Text t -> FD.append fd k t
40+ FormValue_File b fn -> FD.appendBlob fd k b fn
41+ return $ xhrRequest "POST" url $ def & xhrRequestConfig_sendData .~ fd
42+
43+-- | Converts a File (e.g., the output of a 'FileInput') into a 'FormValue'. The filename will be included if it is available.
44+fileToFormValue :: MonadJSM m => File -> m (FormValue File)
45+fileToFormValue f = do
46+ fn <- getName f
47+ return $ FormValue_File f $ Just fn