Elm - Commandes

Dans les chapitres précédents, nous avons abordé les différents composants de l'architecture Elm et leurs fonctions. L'utilisateur et l'application communiquent entre eux à l'aide de Messages.

Prenons un exemple où l'application a besoin de communiquer avec d'autres composants comme un serveur externe, des API, un microservice, etc. pour répondre à la demande de l'utilisateur. Ceci peut être réalisé en utilisant les commandes dans Elm. Les messages et les commandes ne sont pas synonymes. Les messages représentent la communication entre un utilisateur final et l'application tandis que les commandes représentent la manière dont une application Elm communique avec d'autres entités. Une commande est déclenchée en réponse à un message.

La figure suivante montre le flux de travail d'une application Elm complexe -

L'utilisateur interagit avec la vue. La vue génère un message approprié en fonction de l'action de l'utilisateur. Le composant de mise à jour reçoit ce message et déclenche une commande.

Syntaxe

La syntaxe pour définir une commande est la suivante -

type Cmd msg

Le message généré par la vue est passé à la commande.

Illustration

L'exemple suivant envoie une requête à une API et affiche le résultat de l'API.

L'application accepte un numéro de l'utilisateur, le transmet à l'API Numbers. Cette API renvoie des faits liés au nombre.

Les différents composants de l'application sont les suivants -

Module HTTP

Le module Http d'Elm est utilisé pour créer et envoyer des requêtes HTTP. Ce module ne fait pas partie du module principal. Nous utiliserons le gestionnaire de packages elm pour installer ce package.

API

Dans cet exemple, l'application communiquera avec l'API Numbers - "http://numbersapi.com/#42".

Vue

La vue de l'application contient une zone de texte et un bouton.

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

Modèle

Le modèle représente la valeur saisie par l'utilisateur et le résultat qui sera renvoyé par l'API.

type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

Message

L'application a les trois messages suivants -

  • ShowFacts
  • Input
  • NewFactArrived

En cliquant sur le bouton Afficher les faits , le message ShowFacts est transmis à la méthode de mise à jour. Lorsque l'utilisateur tape une valeur dans la zone de texte, le message d' entrée est passé à la méthode de mise à jour. Enfin, lorsque la réponse du serveur Http est reçue, le message NewFactArrived sera transmis à update.

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

Mise à jour

La méthode update renvoie un tuple, qui contient les objets modèle et commande. Lorsque l'utilisateur clique sur le bouton Afficher les faits, le message est transmis à la mise à jour qui appelle alors NumbersAPI.

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
      (model, Cmd.none)

Fonction d'assistance

La fonction d'assistance getRandomNumberFromAPI appelle NumbersAPI et lui transmet le numéro saisi par l'utilisateur. Le résultat renvoyé par l'API est utilisé pour mettre à jour le modèle.

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
         "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)
Sr. No. Méthode Signature La description
1 Http.getString getString: String -> Request String Créez une requête GET et interprétez le corps de la réponse comme une chaîne.
2 Http.send envoyer: (Erreur de résultat a -> msg) -> Request a -> Cmd msg Envoyez une requête Http.

principale

C'est le point d'entrée du projet Elm.

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

Mettre tous ensemble

Step 1 - Créez le dossier CommandApp et le fichier CommandDemo.elm.

Step 2- Installez le module http à l'aide de la commande elm package install elm-lang / http .

Step 2 - Tapez le contenu de CommandDemo.elm comme indiqué ci-dessous -

import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Http

main =
   Html.program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }

-- MODEL
type alias Model =
   { heading : String
   , factText : String
   , input :String
   }

init : (Model, Cmd Msg)
init =
   ( Model "NumbersAPI" "NoFacts" "42"-- set model two fields
   , Cmd.none -- not to invoke api initially
   )

-- UPDATE

type Msg
   = ShowFacts
   |Input String
   | NewFactArrived (Result Http.Error String)

update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
   case msg of
      Input newInput ->
      (Model "NumbersApi typing.." "" newInput ,Cmd.none)
      ShowFacts ->
         (model, getRadmonNumberFromAPI model.input)

      NewFactArrived (Ok newFact) ->
         (Model "DataArrived" newFact "", Cmd.none)

      NewFactArrived (Err _) ->
         (model, Cmd.none)

- VIEW

view : Model -> Html Msg
view model =
   div []
      [ h2 [] [text model.heading]
      ,input [onInput Input, value model.input] []
      , button [ onClick ShowFacts ] [ text "show facts" ]
      , br [] []
      , h3 [][text model.factText]
      ]

-- SUBSCRIPTIONS

subscriptions : Model -> Sub Msg
subscriptions model =
   Sub.none

-- HTTP

getRadmonNumberFromAPI : String->Cmd Msg
getRadmonNumberFromAPI newNo =
   let
      url =
      "http://numbersapi.com/"++newNo
   in
      Http.send NewFactArrived (Http.getString url)

Step 4 - Lancez la commande.

C:\Users\dell\elm\CommandApp> elm make .\CommandDemo.elm

Cela générera le fichier html comme indiqué ci-dessous.