Translate

domingo, 1 de febrero de 2026

Json en Elm




Acabamos de ver un ejemplo que usa HTTP para obtener el contenido de un libro. Pero muchos servidores devuelven datos en un formato especial llamado Notación de Objetos JavaScript, o JSON.

Nuestro siguiente ejemplo muestra cómo obtener datos JSON, lo que nos permite pulsar un botón para mostrar citas aleatorias de una selección aleatoria de libros. 


import Browser

import Html exposing (..)

import Html.Attributes exposing (style)

import Html.Events exposing (..)

import Http

import Json.Decode exposing (Decoder, map4, field, int, string)


-- MAIN

main =

  Browser.element

    { init = init

    , update = update

    , subscriptions = subscriptions

    , view = view

    }


-- MODEL

type Model

  = Failure

  | Loading

  | Success Quote


type alias Quote =

  { quote : String

  , source : String

  , author : String

  , year : Int

  }


init : () -> (Model, Cmd Msg)

init _ =

  (Loading, getRandomQuote)


-- UPDATE

type Msg

  = MorePlease

  | GotQuote (Result Http.Error Quote)


update : Msg -> Model -> (Model, Cmd Msg)

update msg model =

  case msg of

    MorePlease ->

      (Loading, getRandomQuote)


    GotQuote result ->

      case result of

        Ok quote ->

          (Success quote, Cmd.none)


        Err _ ->

          (Failure, Cmd.none)


-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msg

subscriptions model =

  Sub.none


-- VIEW

view : Model -> Html Msg

view model =

  div []

    [ h2 [] [ text "Random Quotes" ]

    , viewQuote model

    ]


viewQuote : Model -> Html Msg

viewQuote model =

  case model of

    Failure ->

      div []

        [ text "I could not load a random quote for some reason. "

        , button [ onClick MorePlease ] [ text "Try Again!" ]

        ]


    Loading ->

      text "Loading..."


    Success quote ->

      div []

        [ button [ onClick MorePlease, style "display" "block" ] [ text "More Please!" ]

        , blockquote [] [ text quote.quote ]

        , p [ style "text-align" "right" ]

            [ text "— "

            , cite [] [ text quote.source ]

            , text (" by " ++ quote.author ++ " (" ++ String.fromInt quote.year ++ ")")

            ]

        ]


-- HTTP

getRandomQuote : Cmd Msg

getRandomQuote =

  Http.get

    { url = "https://elm-lang.org/api/random-quotes"

    , expect = Http.expectJson GotQuote quoteDecoder

    }


quoteDecoder : Decoder Quote

quoteDecoder =

  map4 Quote

    (field "quote" string)

    (field "source" string)

    (field "author" string)

    (field "year" int)


Este ejemplo es bastante similar al anterior:

  • init inicia en el estado Cargando, con un comando para obtener una cita aleatoria.
  • update gestiona el mensaje GotQuote cuando hay una nueva cita disponible. Pase lo que pase, no tenemos comandos adicionales. También gestiona el mensaje MorePlease cuando alguien presiona el botón, emitiendo un comando para obtener más citas aleatorias.
  • view muestra las citas!

La principal diferencia está en la definición de getRandomCatGif. En lugar de usar Http.expectString, hemos cambiado a Http.expectJson. ¿Qué ocurre con esto?


Cuando se solicita a /api/random-quotes una cita aleatoria, el servidor produce una cadena JSON como esta:


{

"quote": "Diciembre solía ser un mes, pero ahora es un año",

"source": "Cartas de un estoico",

"author": "Séneca",

"year": 54

}


No ofrecemos garantías sobre la información aquí contenida. El servidor puede cambiar los nombres de los campos, y estos pueden tener diferentes tipos en distintas situaciones. ¡Es un mundo complejo!

En JavaScript, el enfoque consiste en convertir JSON en objetos JavaScript y esperar que todo salga bien. Pero si hay algún error tipográfico o datos inesperados, se produce una excepción de tiempo de ejecución en alguna parte del código. ¿Era incorrecto el código? ¿Eran incorrectos los datos? ¡Es hora de investigar para averiguarlo!

En Elm, validamos el JSON antes de que llegue a nuestro programa. Por lo tanto, si los datos tienen una estructura inesperada, lo detectamos de inmediato. Es imposible que datos incorrectos se filtren y provoquen una excepción de tiempo de ejecución tres archivos después. Esto se logra con decodificadores JSON.