2016-06-03 9 views
1

Ich frage mich, ob ich Hilfe bei der Iteration einer Liste von Gruppen bekommen kann, eine POST-Anfrage für jede Gruppe einen Raum erstellen, Iteration der Benutzer für jede Gruppe und machen eine POST-Anfrage, um sie diesem bestimmten Raum zuzuweisen.Elm: Iterate Liste Ausführen von mehreren HTTP-Anfragen

Ich habe folgendes Modell.

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

Das gewünschte Ergebnis ist, dass der Raum Foo wurde erstellt und Joe und Mary wurden zugewiesen und Bar wurde erstellt und Jill und Jack zugewiesen wurden.

Die Ansicht, für jetzt, wäre nur eine einfache Schaltfläche, die eine Aktion auslöst.

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

Ich habe 2 erstellt POST-Anfragen:

  1. createRoom: Nehmen Sie ein title, schaffen einen Raum der title mit und schicken Sie das room_id

  2. addUser: nehmen a room_id und name eines Benutzers, fügen Sie die Benutzer dem Raum hinzu und geben Sie den Statuszurück

Beispiel:

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

Ich frage mich, wie Sie diese über Vernähen insgesamt gehen würde, so dass Onclick:

  1. Iterierte jede Gruppe
  2. das machen POST zum Erstellen des Raums
  3. nehmen Sie die room_id aus der Antwort und iterieren die Benutzer
  4. POST die room_id und die Benutzer nennen

Jede Hilfe sehr geschätzt wird.

Antwort

1

Sie haben ein paar verstreute Fehler, auf die ich nicht explizit hinweisen werde, weil der Compiler Ihnen helfen wird, aber Sie haben einen guten Start. Sie haben bereits einige Http Handhabung Cmd s aufgebaut, so dass Sie nur Dinge mit Ihrer update Funktion verdrahten müssen.

Lassen Sie uns Ihr Modell explizit definieren (Sie dies bereits tun, aber es ist nicht in Ihrem Beispiel):

type alias User = 
    { name : String } 

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

type alias Model = 
    { groups : List Group } 

Ihre Funktionen Basiert weg, hier ist, wie ich Ihre Msg Art interpretieren, mit einem kleine Änderung, die eine Liste von Benutzern als Parameter zu CreateRoomsSuccess hinzufügen soll.

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

Jetzt können wir createRoom, um entlang der Liste der Benutzer zwicken passieren zu erstellen. Beachten Sie, dass zu diesem Zeitpunkt keine Benutzer erstellt werden.Es verwendet currying, um eine teilweise angewendete Funktion zu erstellen, so dass, wenn der CreateRoomsSuccess Fall in der update Funktion behandelt wird, es bereits die Liste der Benutzer hat, die erstellt werden müssen (anstatt sie in der Liste model nachzuschlagen):

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

die Liste der Räume zu erstellen, geben Sie einfach die Liste der Gruppen auf eine Liste von Cmd s Karte, die die Post durchführen. Dies wird geschehen, wenn die Schaltfläche geklickt wird:

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

Hier finden Sie die Update-Fälle, wenn Fehler auftreten implementieren. Als nächstes müssen wir die Nachricht CreateRoomsSuccess behandeln. Hier müssen Sie die Liste der Benutzer für eine Gruppe nachschlagen. Auch hier werden Sie die Funktion, die Sie bereits erstellt, die die HTTP-Task Griffe Karte über:

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

Hier finden Sie die AddUserFail und AddUserSuccess Fälle behandeln müssen, aber die oben genannten Beispiele sollen Ihnen helfen, zu verstehen, wie mehrere Nachrichten posten und handeln entsprechend basierend auf dem Erfolg oder Misserfolg von jedem.

+0

Vielen Dank für Ihre ausführliche Antwort. Ich lerne immer so viel von deinen Antworten! –