2017-04-04 212 views
0

我已经成功地引发ELM一个简单的HTTP请求和解码JSON响应到ELM值 - [https://stackoverflow.com/questions/43139316/decode-nested-variable-length-json-in-elm]链HTTP请求和合并JSON响应

问题我面对NOW-

如何链接(并发首选)两个http请求并将json合并到我的新(更新)模型中。注 - 请更新Commands.elm用于访问远程数据

套餐 - krisajenkins /对RemoteData http://package.elm-lang.org/packages/krisajenkins/remotedata/4.3.0/RemoteData

我的代码

GitHub库 - 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 msg model = 
    case msg of 
     Msgs.OnFetchLSLeaders response -> 
      ({ model | lsLeaders = response }, Cmd.none) 

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

回答

3

仍然发射两个并发请求的方式是使用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文件(使用结果的元组,而不是一个附加列表中的例如):

只有当它的所有子级都成功时,最后的元组才会成功。如果其任何子女仍在加载,它仍然处于加载状态。如果有任何孩子失败,则错误是最左边的失败值。