Options
All
  • Public
  • Public/Protected
  • All
Menu

Module "http"

Index

Effect Manager

Const createEffectManager

  • createEffectManager<AppAction>(): EffectManager<typeof home, AppAction, SelfAction, State<AppAction>>
  • Creates the effect manager.

    Type parameters

    • AppAction

    Returns EffectManager<typeof home, AppAction, SelfAction, State<AppAction>>

Requests

get

  • get<A>(url: string, expect: Expect<A>): Cmd<A>
  • Create a GET request.

        import Http
        type Msg
          = GotText (Result Http.Error String)
        getPublicOpinion : Cmd Msg
        getPublicOpinion =
          Http.get
            { url = "https://elm-lang.org/assets/public-opinion.txt"
            , expect = Http.expectString GotText
            }

    You can use functions like [expectString]{@link module:Http.expectString} and [expectJson]{@link module:Http.expectJson} to interpret the response in different ways. In this example, we are expecting the response body to be a String containing the full text of Public Opinion by Walter Lippmann. Note: Use elm/url to build reliable URLs.

    Type parameters

    • A

    Parameters

    • url: string
    • expect: Expect<A>

    Returns Cmd<A>

post

  • post<A>(url: string, body: Body, expect: Expect<A>): Cmd<A>
  • Create a POST request. So imagine we want to send a POST request for some JSON data. It might look like this:

        import Http
        import Json.Decode exposing (list, string)
        type Msg
          = GotBooks (Result Http.Error (List String))
        postBooks : Cmd Msg
        postBooks =
          Http.post
            { url = "https://example.com/books"
            , body = Http.emptyBody
            , expect = Http.expectJson GotBooks (list string)
            }

    Notice that we are using expectJson to interpret the response as JSON. You can learn more about how JSON decoders work [here][] in the guide. We did not put anything in the body of our request, but you can use functions like stringBody and jsonBody if you need to send information to the server. [here]: https://guide.elm-lang.org/interop/json.html

    Type parameters

    • A

    Parameters

    Returns Cmd<A>

request

  • request<A>(method: string, headers: ReadonlyArray<Header>, url: string, body: Body, expect: Expect<A>, timeout: number | undefined, tracker: string | undefined): Cmd<A>
  • Create a custom request. For example, a PUT for files might look like this:

      import File
      import Http
      type Msg = Uploaded (Result Http.Error ())
      upload : File.File -> Cmd Msg
      upload file =
        Http.request
          { method = "PUT"
          , headers = []
          , url = "https://example.com/publish"
          , body = Http.fileBody file
          , expect = Http.expectWhatever Uploaded
          , timeout = Nothing
          , tracker = Nothing
          }

    It lets you set custom headers as needed. The timeout is the number of milliseconds you are willing to wait before giving up. The tracker lets you cancel and track requests.

    Type parameters

    • A

    Parameters

    • method: string
    • headers: ReadonlyArray<Header>
    • url: string
    • body: Body
    • expect: Expect<A>
    • timeout: number | undefined
    • tracker: string | undefined

    Returns Cmd<A>

Header

Header

Header: readonly [string, string]

An HTTP header for configuring requests. See a bunch of common headers here.

header

  • header(name: string, value: string): Header
  • Create a Header.

      header "If-Modified-Since" "Sat 29 Oct 1994 19:43:31 GMT"
      header "Max-Forwards" "10"
      header "X-Requested-With" "XMLHttpRequest"

    Parameters

    • name: string
    • value: string

    Returns Header

Body

Body

Body: readonly [string, unknown] | undefined

Represents the body of a Request.

bytesBody

  • bytesBody(mimeType: string, bytes: Uint8Array): Body
  • Put some Bytes in the body of your Request. This allows you to use elm/bytes to have full control over the binary representation of the data you are sending. For example, you could create an archive.zip file and send it along like this:

        import Bytes exposing (Bytes)
        zipBody : Bytes -> Body
        zipBody bytes =
          bytesBody "application/zip" bytes

    The first argument is a MIME type of the body. In other scenarios you may want to use MIME types like image/png or image/jpeg instead. Note: Use track to track upload progress.

    Parameters

    • mimeType: string
    • bytes: Uint8Array

    Returns Body

emptyBody

  • Create an empty body for your Request. This is useful for GET requests and POST requests where you are not sending any data.

    Returns Body

fileBody

  • fileBody(f: File): Body
  • Use a file as the body of your Request. When someone uploads an image into the browser with elm/file you can forward it to a server. This will automatically set the Content-Type to the MIME type of the file. Note: Use track to track upload progress.

    Parameters

    • f: File

    Returns Body

jsonBody

  • jsonBody(value: {} | ReadonlyArray<unknown> | number | string | boolean): Body
  • Put some JSON value in the body of your Request. This will automatically add the Content-Type: application/json header.

    Parameters

    • value: {} | ReadonlyArray<unknown> | number | string | boolean

    Returns Body

stringBody

  • stringBody(mimeType: string, theString: string): Body
  • Put some string in the body of your Request. Defining jsonBody looks like this:

        import Json.Encode as Encode
        jsonBody : Encode.Value -> Body
        jsonBody value =
          stringBody "application/json" (Encode.encode 0 value)

    The first argument is a MIME type of the body. Some servers are strict about this!

    Parameters

    • mimeType: string
    • theString: string

    Returns Body

Expect

Error

Error: { type: "BadUrl"; url: string } | { type: "Timeout" } | { type: "NetworkError" } | { statusCode: number; type: "BadStatus" } | { body: string; type: "BadBody" }

A Request can fail in a couple ways:

  • BadUrl means you did not provide a valid URL.
  • Timeout means it took too long to get a response.
  • NetworkError means the user turned off their wifi, went in a cave, etc.
  • BadStatus means you got a response back, but the status code indicates failure.
  • BadBody means you got a response back with a nice status code, but the body of the response was something unexpected. The String in this case is a debugging message that explains what went wrong with your JSON decoder or whatever.
  • *Note:** You can use expectStringResponse and expectBytesResponse to get more flexibility on this.

Expect

Expect<A>: { type: "Expect" }

Logic for interpreting a response body.

Type parameters

  • A

Type declaration

  • Readonly type: "Expect"

Json

Json: string | number | boolean | null | ReadonlyArray<Json> | {}

A type representing Json

expectAnyJson

  • Expect valid json but do not care about the contents. Probably not a good idea as skipping checking the contents may cause hard to debug runtime exceptions further ahead.

    Type parameters

    • A

    Parameters

    Returns Expect<A>

expectBytes

  • expectBytes<A, TSuccess>(toMsg: (result: Result<Error, TSuccess>) => A, decoder: (b: unknown) => Result<string, TSuccess>): Expect<A>
  • Expect the response body to be binary data. For example, maybe you are talking to an endpoint that gives back ProtoBuf data:

        import Bytes.Decode as Bytes
        import Http
        type Msg
          = GotData (Result Http.Error Data)
        getData : Cmd Msg
        getData =
          Http.get
            { url = "/data"
            , expect = Http.expectBytes GotData dataDecoder
            }
        -- dataDecoder : Bytes.Decoder Data

    You would use elm/bytes to decode the binary data according to a proto definition file like example.proto. If the decoder fails, you get a BadBody error that just indicates that something went wrong. It probably makes sense to debug by peeking at the bytes you are getting in the browser developer tools or something.

    Type parameters

    • A

    • TSuccess

    Parameters

    • toMsg: (result: Result<Error, TSuccess>) => A
    • decoder: (b: unknown) => Result<string, TSuccess>
        • (b: unknown): Result<string, TSuccess>
        • Parameters

          • b: unknown

          Returns Result<string, TSuccess>

    Returns Expect<A>

expectJson

  • expectJson<A, TSuccess>(toMsg: (result: Result<Error, TSuccess>) => A, decoder: (b: string) => Result<string, TSuccess>): Expect<A>
  • Expect the response body to be JSON. Like if you want to get a random cat GIF you might say:

        import Http
        import Json.Decode exposing (Decoder, field, string)
        type Msg
          = GotGif (Result Http.Error String)
        getRandomCatGif : Cmd Msg
        getRandomCatGif =
          Http.get
            { url = "https://api.giphy.com/v1/gifs/random?api_key=dc6zaTOxFJmzC&tag=cat"
            , expect = Http.expectJson GotGif gifDecoder
            }
        gifDecoder : Decoder String
        gifDecoder =
          field "data" (field "image_url" string)

    The official guide goes through this particular example [here][]. That page also introduces [elm/json][json] to help you get started turning JSON into Elm values in other situations. [here]: https://guide.elm-lang.org/interop/json.html [json]: /packages/elm/json/latest/ If the JSON decoder fails, you get a BadBody error that tries to explain what went wrong.

    Type parameters

    • A

    • TSuccess

    Parameters

    • toMsg: (result: Result<Error, TSuccess>) => A
    • decoder: (b: string) => Result<string, TSuccess>
        • (b: string): Result<string, TSuccess>
        • Parameters

          • b: string

          Returns Result<string, TSuccess>

    Returns Expect<A>

expectString

  • Expect the response body to be a String. Like when getting the full text of a book:

        import Http
        type Msg
          = GotText (Result Http.Error String)
        getPublicOpinion : Cmd Msg
        getPublicOpinion =
          Http.get
            { url = "https://elm-lang.org/assets/public-opinion.txt"
            , expect = Http.expectString GotText
            }

    The response body is always some sequence of bytes, but in this case, we expect it to be UTF-8 encoded text that can be turned into a String.

    Type parameters

    • A

    Parameters

    Returns Expect<A>

expectWhatever

  • Expect the response body to be whatever. It does not matter. Ignore it! For example, you might want this when uploading files:

        import Http
        type Msg
          = Uploaded (Result Http.Error ())
        upload : File -> Cmd Msg
        upload file =
          Http.post
            { url = "/upload"
            , body = Http.fileBody file
            , expect = Http.expectWhatever Uploaded
            }

    The server may be giving back a response body, but we do not care about it.

    Type parameters

    • A

    Parameters

    Returns Expect<A>

Progress

fractionReceived

  • fractionReceived(received: number, size: number | undefined): number
  • Turn Receiving progress into a useful fraction for progress bars.

        fractionReceived { received =   0, size = Just 1024 } == 0.0
        fractionReceived { received = 256, size = Just 1024 } == 0.25
        fractionReceived { received = 512, size = Just 1024 } == 0.5
        -- fractionReceived { received =   0, size = Nothing } == 0.0
        -- fractionReceived { received = 256, size = Nothing } == 0.0
        -- fractionReceived { received = 512, size = Nothing } == 0.0

    The size here is based on the [Content-Length][cl] header which may be missing in some cases. A server may be misconfigured or it may be streaming data and not actually know the final size. Whatever the case, this function will always give 0.0 when the final size is unknown. Furthermore, the Content-Length header may be incorrect! The implementation clamps the fraction between 0.0 and 1.0, so you will just get 1.0 if you ever receive more bytes than promised. Note: If you are streaming something, you can write a custom version of this function that just tracks bytes received. Maybe you show that 22kb or 83kb have been downloaded, without a specific fraction. If you do this, be wary of divide-by-zero errors because size can always be zero! [cl]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Length

    Parameters

    • received: number
    • size: number | undefined

    Returns number

fractionSent

  • fractionSent(sent: number, size: number): number
  • Turn Sending progress into a useful fraction.

        fractionSent { sent =   0, size = 1024 } == 0.0
        fractionSent { sent = 256, size = 1024 } == 0.25
        fractionSent { sent = 512, size = 1024 } == 0.5
        -- fractionSent { sent = 0, size = 0 } == 1.0

    The result is always between 0.0 and 1.0, ensuring that any progress bar animations never go out of bounds. And notice that size can be zero. That means you are sending a request with an empty body. Very common! When size is zero, the result is always 1.0. Note: If you create your own function to compute this fraction, watch out for divide-by-zero errors!

    Parameters

    • sent: number
    • size: number

    Returns number

track

  • track<A>(tracker: string, toMsg: (p: Progress) => A): MySub<A>
  • Track the progress of a request. Create a request where tracker = Just "form.pdf" and you can track it with a subscription like track "form.pdf" GotProgress.

    Type parameters

    • A

    Parameters

    • tracker: string
    • toMsg: (p: Progress) => A
        • (p: Progress): A
        • Parameters

          • p: Progress

          Returns A

    Returns MySub<A>

Cancel

cancel

  • cancel<A>(tracker: string): Cmd<A>
  • Try to cancel an ongoing request based on a tracker.

    Type parameters

    • A

    Parameters

    • tracker: string

    Returns Cmd<A>

Elaborate Expectations

expectBytesResponse

  • expectBytesResponse<A, TError, TSuccess>(toMsg: (r: Result<TError, TSuccess>) => A, toResult: (r: Response<Bytes>) => Result<TError, TSuccess>): Expect<A>
  • Expect a Response with a Bytes body. It works just like expectStringResponse, giving you more access to headers and more leeway in defining your own errors.

    Type parameters

    • A

    • TError

    • TSuccess

    Parameters

    • toMsg: (r: Result<TError, TSuccess>) => A
        • (r: Result<TError, TSuccess>): A
        • Parameters

          Returns A

    • toResult: (r: Response<Bytes>) => Result<TError, TSuccess>
        • (r: Response<Bytes>): Result<TError, TSuccess>
        • Parameters

          • r: Response<Bytes>

          Returns Result<TError, TSuccess>

    Returns Expect<A>

expectStringResponse

  • expectStringResponse<A, TError, TSuccess>(toMsg: (r: Result<TError, TSuccess>) => A, toResult: (r: Response<string>) => Result<TError, TSuccess>): Expect<A>
  • Expect a Response with a String body. So you could define your own expectJson like this:

        import Http
        import Json.Decode as D
        expectJson : (Result Http.Error a -> msg) -> D.Decoder a -> Expect msg
        expectJson toMsg decoder =
          expectStringResponse toMsg <|
            \response ->
              case response of
                Http.BadUrl_ url ->
                  Err (Http.BadUrl url)
                Http.Timeout_ ->
                  Err Http.Timeout
                Http.NetworkError_ ->
                  Err Http.NetworkError
                Http.BadStatus_ metadata body ->
                  Err (Http.BadStatus metadata.statusCode)
                Http.GoodStatus_ metadata body ->
                  case D.decodeString decoder body of
                    Ok value ->
                      Ok value
                    Err err ->
                      BadBody (D.errorToString err)

    This function is great for fancier error handling and getting response headers. For example, maybe when your sever gives a 404 status code (not found) it also provides a helpful JSON message in the response body. This function lets you add logic to the BadStatus_ branch so you can parse that JSON and give users a more helpful message! Or make your own custom error type for your particular application!

    Type parameters

    • A

    • TError

    • TSuccess

    Parameters

    • toMsg: (r: Result<TError, TSuccess>) => A
        • (r: Result<TError, TSuccess>): A
        • Parameters

          Returns A

    • toResult: (r: Response<string>) => Result<TError, TSuccess>
        • (r: Response<string>): Result<TError, TSuccess>
        • Parameters

          • r: Response<string>

          Returns Result<TError, TSuccess>

    Returns Expect<A>

Generated using TypeDoc