A menudo resulta útil obtener información de otras fuentes de internet.
Por ejemplo, supongamos que queremos cargar el texto completo de "Opinión Pública" de Walter Lippmann. Publicado en 1922, este libro ofrece una perspectiva histórica sobre el auge de los medios de comunicación y sus implicaciones para la democracia. Para nuestros propósitos, nos centraremos en cómo usar el paquete elm/http para integrar este libro en nuestro programa.
Si queres ver el ejemplo en acción, hace click en este link: https://elm-lang.org/examples/book
import Browser
import Html exposing (Html, text, pre)
import Http
-- MAIN
main =
Browser.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- MODEL
type Model
= Failure
| Loading
| Success String
init : () -> (Model, Cmd Msg)
init _ =
( Loading
, Http.get
{ url = "https://elm-lang.org/assets/public-opinion.txt"
, expect = Http.expectString GotText
}
)
-- UPDATE
type Msg
= GotText (Result Http.Error String)
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotText result ->
case result of
Ok fullText ->
(Success fullText, Cmd.none)
Err _ ->
(Failure, Cmd.none)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
view : Model -> Html Msg
view model =
case model of
Failure ->
text "I was unable to load your book."
Loading ->
text "Loading..."
Success fullText ->
pre [] [ text fullText ]
Algunas partes de esto deberían resultar familiares de ejemplos anteriores de la arquitectura Elm. Seguimos teniendo un modelo de nuestra aplicación. Seguimos teniendo una actualización que reacciona a los mensajes. Seguimos teniendo una función de vista que muestra todo en pantalla.
Las nuevas partes amplían el patrón principal que vimos antes con algunos cambios en init y update, y la incorporación de la suscripción.
La función init describe cómo inicializar nuestro programa:
init : () -> (Model, Cmd Msg)
init _ =
( Loading
, Http.get
{ url = "https://elm-lang.org/assets/public-opinion.txt"
, expect = Http.expectString GotText
}
)
Como siempre, debemos generar el modelo inicial, pero ahora también generamos un comando que indica lo que queremos hacer inmediatamente. Ese comando generará un mensaje que se introduce en la función de actualización.
Nuestro sitio web del libro se inicia en estado de carga y queremos obtener el texto completo. Al realizar una solicitud GET con Http.get, especificamos la URL de los datos que queremos obtener y qué datos esperamos que contengan. En nuestro caso, la URL apunta a datos del sitio web de Elm y esperamos que sea una cadena grande que podamos mostrar en pantalla.
La línea Http.expectString GotText indica algo más que esperamos una cadena. También indica que, cuando recibamos una respuesta, esta debe convertirse en un mensaje GotText:
type Msg
= GotText (Result Http.Error String)
-- GotText (Ok "The Project Gutenberg EBook of ...")
-- GotText (Err Http.NetworkError)
-- GotText (Err (Http.BadStatus 404))
Tengamos en cuenta que usamos el tipo Result, mencionado en un par de secciones anteriores. Esto nos permite considerar completamente los posibles fallos en nuestra función de actualización. Hablando de funciones de actualización...
Nuestra función de actualización también devuelve un poco más de información:
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
GotText result ->
case result of
Ok fullText ->
(Success fullText, Cmd.none)
Err _ ->
(Failure, Cmd.none)
Al observar la firma de tipo, vemos que no solo devolvemos un modelo actualizado. También generamos un comando que indica lo que queremos que haga Elm.
Pasando a la implementación, realizamos la coincidencia de patrones con los mensajes de forma normal. Cuando llega un mensaje GotText, inspeccionamos el resultado de nuestra solicitud HTTP y actualizamos nuestro modelo según si fue un éxito o un fracaso. La novedad es que también proporcionamos un comando.
En caso de obtener el texto completo correctamente, ejecutamos Cmd.none para indicar que no hay más trabajo que hacer. ¡Ya obtuvimos el texto completo!
Y en caso de algún error, también ejecutamos Cmd.none y simplemente nos rendimos. El texto del libro no se cargó. Si quisiéramos ser más sofisticados, podríamos realizar la coincidencia de patrones con Http.Error y reintentar la solicitud si se agota el tiempo de espera o algo similar.
La cuestión es que, independientemente de cómo decidamos actualizar nuestro modelo, también podemos ejecutar nuevos comandos. ¡Necesito más datos! ¡Quiero un número aleatorio! Etc.
La otra novedad de este programa es la función de suscripción. Permite consultar el modelo y decidir si se desea suscribirse a cierta información. En nuestro ejemplo, usamos Sub.none para indicar que no necesitamos suscribirnos a nada, pero pronto veremos un ejemplo de un reloj al que queremos suscribirnos a la hora actual.
Al crear un programa con Browser.element, configuramos un sistema como este:
Podemos ejecutar comandos desde init y update. Esto nos permite, por ejemplo, realizar solicitudes HTTP cuando queramos. También podemos suscribirnos a información interesante. (¡Veremos un ejemplo de suscripciones más adelante!)
