Elm:迭代列表执行多个HTTP请求

时间:2016-06-03 13:32:17

标签: http elm

我想知道我是否可以通过迭代组列表获得一些帮助,为每个组创建POST请求以创建“房间”,为每个组迭代用户并发出POST请求以将其分配给此特定的房间。

我有以下型号。

model = {
  groups = [
    {
      title = "Foo"
      , users = [
        { name = "Joe" }
        , { name = "Mary" }
      ]
    },
    {
      title = "Bar"
      , users = [
        { name = "Jill" }
        , { name = "Jack" }
      ]
    }
  ]
}

期望的结果是创建了房间Foo并且分配了Joe和Mary,并且创建了Bar并且分配了Jill和Jack。

目前,该视图只是一个触发操作的简单按钮。

div []
  [ button [ onClick InviteUsersToRoom ] [ text "Invite users to room" ] ]

我创建了2个POST请求:

  1. createRoom :点击title,使用title创建一个房间并返回room_id

  2. addUser :获取room_id和用户的name,将用户添加到会议室并返回ok的状态

  3. 示例:

    -- create a room for each group
    -- passing in `title` as the room name
    -- which will return the room id from `decodeCreateRoomResponse`
    
    createRoom : String -> String -> Cmd Msg
    createRoom title =
      Task.perform
        CreateRoomsFail
        CreateRoomsSuccess
        (Http.post
          decodeCreateRoomResponse
          ("https://some_api?room=" ++ title)
          Http.empty
        )
    
    
    decodeCreateRoomResponse : Json.Decoder String
    decodeCreateRoomResponse =
      Json.at ["room", "id"] Json.string
    
    
    -- add a user to a room using a `room_id` and the user's name
    -- returns a bool from `decodeAddUserResponse`
    
    addUser : String -> String -> Cmd Msg
    addUser room_id user =
      Task.perform
        AddUserFail
        AddUserSuccess
        (Http.post
          decodeCreateChannelResponse
          ("https://some_api?room=" ++ room_id ++ "&user=" ++ user)
          Http.empty
        )
    
    
    decodeAddUserResponse : Json.Decoder String
    decodeAddUserResponse =
      Json.at ["ok"] Json.bool
    

    我想知道你如何完全拼凑这个,所以onclick:

    1. 迭代每个小组
    2. 制作POST以创建会议室
    3. 从响应中获取room_id并迭代用户
    4. 发布room_id和用户名
    5. 感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

你有一些我不会明确指出的分散错误,因为编译器会帮助你,但是你有一个良好的开端。您已经建立了一些Http处理Cmd,因此您只需要使用update函数进行连接。

让我们明确定义您的模型(您可能已经这样做但在您的示例中不是这样):

type alias User =
  { name : String }

type alias Group =
  { title : String
  , users : List User
  }

type alias Model =
  { groups : List Group }

根据您的功能,这里是我如何解释您的Msg类型,只有一个小的更改是将用户列表添加为CreateRoomsSuccess的参数。

type Msg
  = InviteUsersToRoom
  | CreateRoomsFail Http.Error
  | CreateRoomsSuccess (List User) String
  | AddUserFail Http.Error
  | AddUserSuccess Bool

现在我们可以调整createRoom以传递要创建的用户列表。请注意,目前尚未创建任何用户。它使用currying来创建部分应用的函数,以便在CreateRoomsSuccess函数中处理update的情况时,它已经有了需要创建的用户列表(而不是必须查看它们在model列表中):

createRoom : Group -> Cmd Msg
createRoom group =
  Task.perform
    CreateRoomsFail
    (CreateRoomsSuccess group.users)
    (Http.post
      decodeCreateRoomResponse
      ("https://some_api?room=" ++ group.title)
      Http.empty
    )

要创建房间列表,只需将组列表映射到执行帖子的Cmd列表即可。单击按钮时会发生这种情况:

case action of
  InviteUsersToRoom ->
    model ! List.map createRoom model.groups
    ...

您必须在发生错误时实施更新案例。接下来,我们必须处理CreateRoomsSuccess消息。这是您需要查找组的用户列表的位置。同样,您将映射已经创建的处理Http任务的函数:

case action of
  ...
  CreateRoomsSuccess users roomID ->
    model ! List.map (addUser roomID << .name) users
  ...

您必须处理AddUserFailAddUserSuccess个案,但上述示例可帮助您了解如何发布多条消息,并根据每条消息的成功或失败采取相应行动。