json - 在 ELM 中链接 http 请求并合并 json 响应

标签 json http elm

我已成功在 ELM 中触发一个简单的 http 请求并将 JSON 响应解码为 ELM 值 - [https://stackoverflow.com/questions/43139316/decode-nested-variable-length-json-in-elm]

我现在面临的问题-

如何链接(首选并发)两个 http 请求并将 json 合并到我的新(更新)模型中。注意 - 请查看更新后的 Commands.elm

用于访问远程数据的包 - krisajenkins/remotedata http://package.elm-lang.org/packages/krisajenkins/remotedata/4.3.0/RemoteData

我的代码的 Github repo - https://github.com/areai51/my-india-elm

以前的工作代码 -

模型.elm

type alias Model =
    { leaders : WebData (List Leader)
    }

initialModel : Model
initialModel =
    { leaders = RemoteData.Loading
    }

Main.elm

init : ( Model, Cmd Msg )
init =
    ( initialModel, fetchLeaders )

Commands.elm

fetchLeaders : Cmd Msg
fetchLeaders =
    Http.get fetchLeadersUrl leadersDecoder
        |> RemoteData.sendRequest
        |> Cmd.map Msgs.OnFetchLeaders


fetchLeadersUrl : String
fetchLeadersUrl =
    "https://data.gov.in/node/85987/datastore/export/json"

Msgs.elm

type Msg
    = OnFetchLeaders (WebData (List Leader))

Update.elm

update msg model =
    case msg of
        Msgs.OnFetchLeaders response ->
            ( { model | leaders = response }, Cmd.none )

更新的代码 - (需要 Commands.elm 方面的帮助)

模型.elm

type alias Model =
    { lsLeaders : WebData (List Leader)
    , rsLeaders : WebData (List Leader)           <------------- Updated Model
    }


initialModel : Model
initialModel =
    { lsLeaders = RemoteData.Loading
    , rsLeaders = RemoteData.Loading
    }

Main.elm

init : ( Model, Cmd Msg )
init =
    ( initialModel, fetchLeaders )

Commands.elm

fetchLeaders : Cmd Msg
fetchLeaders =                                  <-------- How do I call both requests here ? And fire separate msgs
    Http.get fetchLSLeadersUrl lsLeadersDecoder    <----- There will be a different decoder named rsLeadersDecoder
        |> RemoteData.sendRequest
        |> Cmd.map Msgs.OnFetchLSLeaders


fetchLSLeadersUrl : String
fetchLSLeadersUrl =
    "https://data.gov.in/node/85987/datastore/export/json"


fetchRSLeadersUrl : String                     <------------------ New data source
fetchRSLeadersUrl =
    "https://data.gov.in/node/982241/datastore/export/json"

Msgs.elm

type Msg
    = OnFetchLSLeaders (WebData (List Leader))
    | OnFetchRSLeaders (WebData (List Leader))         <-------- New message

Update.elm

update msg model =
    case msg of
        Msgs.OnFetchLSLeaders response ->
            ( { model | lsLeaders = response }, Cmd.none )

        Msgs.OnFetchRSLeaders response ->                  <--------- New handler
            ( { model | rsLeaders = response }, Cmd.none )

最佳答案

触发两个并发请求的方法是使用Cmd.batch:

init : ( Model, Cmd Msg )
init =
    ( initialModel, Cmd.batch [ fetchLSLeaders, fetchRSLeaders ] )

无法保证哪个请求会先返回,也无法保证它们都会成功。例如,一个可能会失败,而另一个会成功。

你提到你想合并结果,但你没有说明合并是如何工作的,所以我假设你想将领导者列表附加到一个列表中,这对如果您只需处理单个 RemoteData 值而不是多个值,您的应用程序。

您可以使用 mapandMap 将多个 RemoteData 值与自定义函数合并在一起。

mergeLeaders : WebData (List Leader) -> WebData (List Leader) -> WebData (List Leader)
mergeLeaders a b =
    RemoteData.map List.append a
        |> RemoteData.andMap b

请注意,我在那里使用了 List.append。这实际上可以是接受两个列表并根据需要合并它们的任何函数。

如果您更喜欢应用程序风格的编程,可以将以上内容转换为以下中缀版本:

import RemoteData.Infix exposing (..)

mergeLeaders2 : WebData (List Leader) -> WebData (List Leader) -> WebData (List Leader)
mergeLeaders2 a b =
    List.append <$> a <*> b

根据 andMap 上的文档(在其示例中使用结果元组而不是附加列表):

The final tuple succeeds only if all its children succeeded. It is still Loading if any of its children are still Loading. And if any child fails, the error is the leftmost Failure value.

关于json - 在 ELM 中链接 http 请求并合并 json 响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43205588/

相关文章:

javascript - jQuery TextExt : Tags with custom data objects

arrays - 索引处的增量元素

elm - 键盘按键信号丢失

java - Jersey 传递一个空的 JSON

android - 按日期对 ListView 进行排序?

python - Django 序列化程序给出 'str' 对象没有属性 '_meta' 错误

ruby - 通过 Net::HTTP 在 Ruby 中发送 http post 请求

javascript - 如何使用 Jade 和 Node.js 迭代 JSON 数组

java - 带有 Java 套接字的 HTTP 客户端

elm - 在 elm 中对 case 表达式进行分组 (0.18)