2
votes

I have successfully implemented a delete player method for the elm tutorial. However I cannot get the model to update without manually sending a ForchFetch msg (via clicking a button) that gets the players from the server again. This is my code:

My delete button:

deleteBtn : Player -> Html.Html Msg
deleteBtn player =
    let
        message =
            Msgs.Delete player
    in
       a
            [ class "btn regular", onClick message]
            [ i [ class "fa fa-pencil mr1" ] [], text "Delete" ]

My delete messages:

type Msg = 
    | Delete Player
    | OnDeletePlayer (Result Http.Error Player) 
    | ForceFetch
    | OnFetchPlayers (WebData (List Player))

My update function:

update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
        Msgs.ForceFetch ->
          (model, fetchPlayers)
        Msgs.OnFetchPlayers response -> 
        ( { model | players = response }, Cmd.none )
        Msgs.Delete player ->
          (model, deletePlayerCmd player)

        Msgs.OnDeletePlayer (Ok player) ->
          (updateDeletedPlayerList model player, Cmd.none)

        Msgs.OnDeletePlayer (Err player) ->
          (model, Cmd.none)

updateDeletedPlayerList : Model -> Player -> Model 
updateDeletedPlayerList model deletedPlayer =     
     let
         updatedPlayers = RemoteData.map (List.filter (\p -> deletedPlayer /= p)) model.players
     in
         { model | players = updatedPlayers}

deletePlayerCmd : Player -> Cmd Msg
deletePlayerCmd player =
      Http.send Msgs.OnDeletePlayer (deletePlayerRequest player)

deletePlayerRequest : Player -> Http.Request Player
deletePlayerRequest player =
 Http.request
        { body = Http.emptyBody
        , expect = Http.expectJson playerDecoder
        , headers = []
        , method = "DELETE"
        , timeout = Nothing
        , url = savePlayerUrl player.id
        , withCredentials = False
        }
fetchPlayers : Cmd Msg
fetchPlayers =
    Http.get fetchPlayersUrl playersDecoder 
        |> RemoteData.sendRequest 
        |> Cmd.map Msgs.OnFetchPlayers

And for good measure my model:

type alias Model =
    { players : WebData (List Player)
    , route : Route
    , newPlayerName : String
    , newPlayerId : String
    , newPlayerLevel : Int
    }

Edit:

I have tried incorporating fetchPlayers in the following manner with no success:

Msgs.OnDeletePlayer (Ok player) ->
          (updateDeletedPlayerList model player, fetchPlayers)
1
If ForceFetch works, I don't see why your attempt in your edit doesn't work. Are you sure the the response ends up being Ok and not Err?Dogbert
I solved it, I'll update the answer shortly.Jimbo
If you are comparing player records in the filter they might not match as what you get from the server could be different. Better do a comparison for just the player.id.Sebastian

1 Answers

1
votes

You need to update the model in your code if you don't want to fetch it after deleting, so where you have:

Msgs.Delete player ->
          (model, deletePlayerCmd player)

you need to change 'model' to a function that will remove the player from it:

    Msgs.Delete player ->
        (removePlayer player model, deletePlayerCmd player)

...
removePlayer : Player -> Model -> Model
...