XhrRequest with reflex / reflex-dom

时间:2015-05-15 16:32:29

标签: haskell ghcjs reflex

我想执行一个基本的Ajax请求,就是这样。

我使用reflex作为前端,Scotty作为后端。 Firefox Web控制台告诉我请求是成功的,我在那里看到了预期的结果。但该网站从Just "default"切换为Nothing而不是Just "success!"

这是一个完整的最小例子:

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

Scotty部分:

{-# 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!"

由于调试工具告诉我请求是成功的,我怀疑错误在decodeXhrResponse附近,但我有点失去了我应该继续调试,因为它只是被编译为(不可读)的Javascript。

我使用GitHub的try-reflex Nix脚本来设置所有内容,并在Nix环境中使用ghcjs hello.hs进行编译。

编辑:添加curl的输出:

$ curl -G http://localhost:3000/mystring
success!% 

2 个答案:

答案 0 :(得分:6)

在freenode var list = new List<KeyValuePair<string, object>>(); list.Add(new KeyValuePair<string, object>("string", "Hello, World!")); list.Add(new KeyValuePair<string, object>("int", 42)); list.Add(new KeyValuePair<string, object>("bool", true)); foreach (var item in list) Console.WriteLine("[{0}] = {1}", item.Key, item.Value); 的帮助下,我找到了一个解决方案:将#reflex-frp替换为decodeXhrResponse并使用_xhrResponse_body替换默认字符串:

Text

buttonDyn <- holdDyn (Just $ T.pack "default") $ fmap _xhrResponse_body asyncEvent 期待某种JSON,虽然我曾尝试通过Scotty提供JSON,但它仍然没有用。

答案 1 :(得分:0)

我编写了这个简化的辅助函数,基本上是从反射中检索远程URL:

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