在ELM中链式http请求和合并json响应 [英] Chain http request and merge json response in ELM

查看:165
本文介绍了在ELM中链式http请求和合并json响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I've succeeded in triggering a simple http request in ELM and decoding the JSON response into an ELM value - [https://stackoverflow.com/questions/43139316/decode-nested-variable-length-json-in-elm]

我现在面临的问题 -

The problem I'm facing now-

如何链接(并发首选)两个http请求并合并json进入我的新(更新)模型。注意 - 请参阅更新的Commands.elm

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

Package used to access remote data - krisajenkins/remotedata http://package.elm-lang.org/packages/krisajenkins/remotedata/4.3.0/RemoteData

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

Github repo of my code - https://github.com/areai51/my-india-elm

以前的工作代码 -

Models.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)

Models.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

The way to fire off two concurrent requests is to use Cmd.batch:

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

无法保证首先返回哪个请求,并且不能保证他们都会成功。例如,一方可能会失败而另一方成功。

There is no guarantee on which request will return first and there is no guarantee that they will both be successful. One could fail while the other succeeds, for example.

您提到要合并结果,但您没有说合并如何工作,所以我我们只是假设你想在一个列表中将领导者列表附加在一起,如果你只需要处理一个 RemoteData 值,它对你的应用程序会很有用。

You mention that you want to merge the results, but you didn't say how the merge would work, so I'll just assume you want to append the lists of leaders together in one list, and it will be useful to your application if you had only to deal with a single RemoteData value rather than multiple.

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

You can merge multiple RemoteData values together with a custom function using map and andMap.

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

请注意我正在使用 List.append 那里。这可以是任何需要两个列表并将它们合并的函数。

Notice that I'm using List.append there. That can really be any function that takes two lists and merges them however you please.

如果您更喜欢编程风格,上面的内容可以转换为以下中缀version:

If you prefer an applicative style of programming, the above could be translated to the following infix version:

import RemoteData.Infix exposing (..)

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

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

According to the documentation on andMap (which uses a result tuple rather than an appended list in its example):


最终元组只有在其所有子元素都成功后才会成功。如果其中任何一个孩子仍在加载,它仍在加载。如果任何一个孩子失败,那么错误就是最左边的失败值。

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.

这篇关于在ELM中链式http请求和合并json响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆