I want to perform a basic Ajax request, that's all.
I use reflex
for the frontend and Scotty
for the backend. The Firefox Web Console tells me the request was a success and I see the expected result there. But the website switches from Just "default"
to Nothing
instead of Just "success!"
.
Here is a complete minimal example:
import Reflex (holdDyn)
import Reflex.Dom (button, el, mainWidget, display)
import Reflex.Dom.Xhr (performRequestAsync, xhrRequest, decodeXhrResponse)
import Reflex.Class (tag, constant)
import Data.Default (def)
main :: IO ()
main = do
mainWidget $ el "div" $ do
buttonEvent <- button "click me"
let defaultReq = xhrRequest "GET" "mystring" def --served by Scotty
asyncEvent <- performRequestAsync (tag (constant defaultReq) buttonEvent)
buttonDyn <- holdDyn (Just "default") $ fmap decodeXhrResponse asyncEvent
display buttonDyn
and the Scotty
part:
{-# LANGUAGE OverloadedStrings #-}
import Web.Scotty
import Network.Wai.Middleware.Static
main = scotty 3000 $ do
middleware $ staticPolicy (noDots >-> addBase "/mnt/b/haskell/try-reflex/hello.jsexe")
get "/" $ do
file "/mnt/b/haskell/try-reflex/hello.jsexe/index.html"
get "/mystring" $ html "success!"
Since the debug tools tell me the request was a success, I suspect the error somewhere near decodeXhrResponse
but I am a bit lost how I should proceed debugging since it just gets compiled to (unreadable) Javascript.
I used the try-reflex Nix script from GitHub to set up everything and compiled with ghcjs hello.hs
in the Nix environment.
Edit: Adding the output of curl
:
$ curl -G http://localhost:3000/mystring
success!%
With help from #reflex-frp
on freenode I found a solution: replacing decodeXhrResponse
with _xhrResponse_body
and using Text
for the default string worked:
buttonDyn <- holdDyn (Just $ T.pack "default") $ fmap _xhrResponse_body asyncEvent
decodeXhrResponse
expects some sort of JSON and although I tried to serve JSON via Scotty at one point it still didn't work.
I wrote this simplified helper function to basically retrieve a remote URL from reflex:
curlGet :: MonadWidget t m => Text -> m (Event t Text)
curlGet url = do
let req = xhrRequest "GET" url def
pb <- getPostBuild
asyncReq <- performRequestAsync (tag (constant req) pb)
pure $ fmap (fromMaybe "Unknown error" . _xhrResponse_responseText) asyncReq
来源:https://stackoverflow.com/questions/30264504/xhrrequest-with-reflex-reflex-dom