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

标签 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。

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

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

我创建了 2 个 POST 请求:

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

  2. addUser:取 room_id和用户的 name , 将用户添加到房间并返回 ok 的状态

例子:

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

我想知道您将如何将其完全拼接起来,以便点击:

  1. 迭代每个组
  2. 创建 POST 以创建房间
  3. 从响应中获取 room_id 并迭代用户
  4. 发布 room_id 和用户名

感谢任何帮助。

最佳答案

您有一些分散的错误,我不会明确指出这些错误,因为编译器会帮助您,但您已经有了一个良好的开端。您已经有一些 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例,但上面的示例应该可以帮助您了解如何发布多条消息并根据每条消息的成功或失败采取相应的行动。

关于http - Elm:迭代列表执行多个 HTTP 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37615801/

相关文章:

elm - 对 "Html msg"感到困惑

drop-down-menu - 如何在 Elm lang 中使用选择(下拉)标签

http - PUT 和 DELETE HTTP 方法有任何性能优势吗?

visual-studio-code - Elm VSCode 插件在保存时未格式化

Elm 找不到依赖项中的模块

jquery - Chrome 错误地解释了 JSONP 请求中的相对重定向

elm - 如何在不为每条消息复制整个结构的情况下传递状态?

ruby - 如何在 Ruby Net::HTTP 中实现 cookie

java - Android - ErrnoException : socket failed: EMFILE (Too many open files) when making http requests

perl - 哪些 http header 可以在浏览器后退按钮上抑制 "This document is no longer available."?