Search code examples
elm

How to avoid Expect msg with HTTP 2.0.0 in elm?


In elm's Http 1.0.0 package, I could send a custom request like:

post : Endoint -> List (Http.Header) -> Http.Body -> Decoder a -> Http.Request a
post url headers body decoder =
    Http.request
        { method = "POST"
        , headers = headers
        , url = url
        , body = body
        , expect = Http.expectJson decoder
        , timeout = Nothing
        , withCredentials = False
        }

With the post function I wrote above, I can simply call it with, say, a Decoder String, and after the Http request sends, the response string will be decoded and returned. period. No need to create a Msg like:

type Msg
    = GotText (Result Http.Error String)

And no need to write a branch in update to handle this Msg.

However, as of Http 2.0.0, the expect argument is of type Expect msg, not Expect a, meaning that writing the Msg variation and additional branch to update will now be required.

I am writing an Api.elm file which makes Http requests. However, this means that now it will have to have its own Msg type and update function to run after these requests respond.

I used to think that Home.elm should only respond to messages from Home.Msg and Home.update not Api.Msg and Api.update. Am I wrong? Should Api.elm have its own Msg type and update function that changes other pages? Or would there be a better way to do this?


Solution

  • To clarify what I was explaining in my question:

    A custom request in Elm's HTTP 2.0.0 package looks like this:

    request : 
      { method : String
      , headers : List Header
      , url = String
      , body = Body
      , expect = Expect msg
      , timeout = Maybe Float
      , withCredentials = Maybe String
      }
      -> Cmd msg
    

    Wheras in Http 1.0.0 it looked like this:

    request :
      { method : String
      , headers : List Header
      , url : String
      , body : Body
      , expect : Expect a
      , timeout : Maybe Float
      , withCredentials : Bool
      }
      -> Request a
    

    The difference is that using the custom request from HTTP 2.0.0, I needed to pass-in a Msg to use this request.

    Now, my problem was: I was using an Api.elm file. Every time I needed to issue an HTTP request, I would call Api.request arg1 arg2... from, say, Login.elm.

    Since the request function in Api.elm demanded a Msg type, for, in this case, a login request I thought I would have to define a Msg of GotLogin within Api.elm and then handle how GotLogin would update Login.elm by writing an update branch for GotLogin within Api.elm.

    However, I could just define a GotLogin Msg in Login.elm and pass that into Api.request. Since I've defined GotLogin in Login.elm, I would put a GotLogin branch in the update function of Login.elm, instead of Api.elm.

    This also applies for any other request type from any other page (Signup.elm, Home.elm,...), meaning that Api.elm, should not have its own update function that updates other pages.

    The whole point of Login.elm having its own update function, is that it should only be affected by the branches of its own update function, not ones from Api.elm.