XhrRequest with reflex/reflex-dom

2020-07-10 09:05发布

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!% 

2条回答
beautiful°
2楼-- · 2020-07-10 09:15

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
查看更多
疯言疯语
3楼-- · 2020-07-10 09:16

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.

查看更多
登录 后发表回答