Fermer

janvier 28, 2020

Un guide pratique pour angulaire: gestion des opérations HTTP


Faire des requêtes HTTP et traiter du code asynchrone est vital pour de nombreuses applications. Dans cet article, je vais vous montrer comment gérer les opérations HTTP dans Angular et comment travailler avec les observables.

Angular est un cadre pour créer des applications dynamiques côté client en utilisant HTML, CSS et JavaScript. Il dispose d'un bel outil CLI qui aide à la productivité des développeurs et à la génération de code qui suit le guide de conception angulaire recommandé afin que vous puissiez créer des applications rapides, réactives et modulaires. Dans cet article, je vais vous montrer comment effectuer des requêtes HTTP et travailler avec les observables RxJS.

Si vous voulez continuer à lire, vous devez déjà avoir une compréhension des composants, directives, modules, liaison de données, services et injection de dépendance en angulaire. Si vous ne connaissez pas ces choses, vous êtes en bonne compagnie parce que j'ai écrit à leur sujet ??. Voici les liens vers les articles que j'ai écrits couvrant ces sujets:

  1. Un guide pratique pour Angular: environnement et configuration de projet
  2. Un guide pratique pour Angular: composants et modules Ng
  3. Un guide pratique pour Angular: Liaison de données et directives
  4. Un guide pratique pour l'injection angulaire: services et dépendances

L'application que nous allons créer ensemble pendant que vous parcourez cet article s'appuie sur l'exemple d'application des articles que j'ai énumérés ci-dessus. Si vous avez lu et travaillé avec moi sur ces articles, vous devriez avoir le code complet. Sinon, vous pouvez télécharger le projet sur GitHub . Lorsque vous le téléchargez, vous devez ensuite copier le contenu du dossier src-part-4 dans le dossier src si vous souhaitez coder pendant que vous lisez.

Données JSON

Avant de procéder à une requête HTTP, nous devons configurer un serveur qui devrait savoir comment répondre aux requêtes HTTP et renvoyer les bonnes données. Cependant, nous ne créerons aucun serveur. Nous allons créer un fichier JSON et configurer l'application afin que la CLI angulaire puisse servir le fichier à sa demande.

Pour créer ce fichier JSON, ajoutez un nouveau fichier src / api / dépenses.json avec le contenu ci-dessous.

 [
   {
     "description" :   "Premier achat pour le mois" 
     "montant" : [19659020] 20 
     "date" :   "2019-08-12" 
  } 
   {
     "description" :   ] "Vélo pour Amy" 
     "montant" :   10 
     "date" :   "2019-08-08" [19659013]} 
   {
     "description" :   "Premiers achats pour le mois" 
     "montant" :   14  ]
     "date" :   "2019-07-12" 
  } 
   {
     "description" :   "Premiers achats pour le mois "
    " am ount ":   20 
    " date ":  " 2019-06-12 "
  } 
   {
    " description ":  " Deuxième magasinage du mois "
    " montant ":   25 
    " date ": [19659016] "2019-06-22" 
  } 
   {
     "description" :   "Deuxième magasinage du mois" 
     "montant" :   19 
     "date" :   "2019-08-24" 
  } 
   {
     "description" :   "Beach trip" 
     "montant" :   210 
     "date" :   "2019-08 -03 "
  } 
   {
    " description ":  " Gajeel's Party "
    " montant ":   102 
     "date" :   "2019-07-22" 
  } 
   {
     "description" [19659015]:   "Scooter" 
     "montant" :   310 
     "date" :   "2019-06-19 "
  } 
] 

Ensuite, nous devons configurer le paramètre de génération du projet dans angular.json afin qu'il serve le fichier JSON nouvellement ajouté lorsqu'il est demandé. Ouvrez angular.json accédez à la ligne 44 et mettez à jour le tableau comme suit:

 "assets" :   [ "src / favicon. ico " " src / assets " " src / api "] 

Ce tableau contient des actifs pour l'application, qui seront servis par le serveur de développement lorsque vous démarrez l'application. Nous venons d'ajouter src / api à la liste. Quel que soit le fichier ajouté, il sera servi à partir de locahost: PORT / api / . Le fichier dépenses.json que nous avons ajouté proviendra de locahost: PORT / api / dépenses.json .

Utilisation du service HttpClient

De nombreux navigateurs prennent en charge deux API pour faire des requêtes HTTP – l'API XMLHttpRequest et Fetch . Angular fournit le service HttpClient comme moyen de communiquer avec des serveurs distants via HTTP. Le HttpClient fournit une API simple à utiliser pour travailler avec HTTP et s'appuie sur l'API XMLHttpRequest . Il vous permet d'intercepter la demande et la réponse, de travailler avec les API observables d'utiliser des objets de demande et de réponse typés, de réessayer les demandes ayant échoué et de tester le code qui repose sur HTTP.

Le HttpClient Le service est enregistré dans le HttpClientModule . Pour utiliser ce service, nous devons importer le module nécessaire à partir de @ angular / common / http .

Ouvrez le fichier src / app / app.module.ts et ajoutez le déclaration d'importation suivante:

 import   { HttpClientModule }   de   "@ angular / common / http" ; 

Ajoutez puis ajoutez le HttpClientModule module du tableau des importations:

 importations :   [ BrowserModule  AppRoutingModule  HttpClientModule ] [19659139] Cela rend le service  HttpClient  disponible pour les services et composants que vous définissez dans le projet. 

Nous mettrons à jour le service ExpenseService pour récupérer les données du fichier JSON via HTTP. Ouvrez src / app / dépenses / dépenses.service.ts et mettez à jour la définition de classe comme vous le voyez ci-dessous:

 export   classe   ExpenseService   {
   privé  url  =   "api / dépenses.json" ; 
   constructeur  ( privé  http :  HttpClient ) [19659142] {} 

   getExpenses  ( date :   chaîne ) :  Observable  < IExpense  [] >   {
     retour   ceci .  http .  obtenez  < IExpense  [[1965901515] ]] >  ( ceci .  url ) .  pipe  (
       carte  ( dépenses  =>   {
         retourne  dépenses .  filtre  ( e  =>  e .  date .  comprend  ( date ) ) ; 
      } ) 
    ) ; 
   ]} 

   getTotalSpending  ( date :   chaîne ) :  Observable  < numéro >   {  { 
     retournez   ceci .  getExpenses  ( date ) .  pipe  (
       map  ( ] dépenses  =>   {
         retour  dépenses
          .  filtre  ( e  =>  e .  date .  comprend  ([ date [ date ) ) ) 
          .  réduire  ( ( précédent  actuel )   =>  précédent  ] +  actuel .  montant   0 ) ; 
      } ) 
    ) ; 
  } 
  } 
  } 
} 

Vous devriez remarquer que le service HttpClient est injecté en tant que dépendance et est utilisé dans les deux méthodes définies dans la classe. Pour effectuer une demande GET, vous utilisez la méthode get () dans HttpClient avec l'URL du service auquel vous souhaitez accéder sur le serveur distant comme paramètre. Dans notre cas, c'est api / dépenses.json comme vous pouvez le voir dans le code ci-dessus. La réponse peut être tapée, c'est pourquoi vous voyez this.http.get et cela fait que la méthode retourne les données en fonction du type spécifié. Le type de retour pour cette méthode est un observable RxJS.

RxJS (Reactive Extensions for JavaScript) est une bibliothèque de programmation réactive que nous pouvons utiliser pour composer des programmes asynchrones et basés sur des événements en utilisant des séquences observables. Les observables nous aident à gérer les données asynchrones (telles que les données provenant d'une API Web) et traitent ces valeurs futures comme une collection invocable. Le système d'événement d'Angular est basé sur des observables.

La méthode pipe () que vous avez vue est utilisée pour composer des opérateurs observables. Les opérateurs sont utilisés pour manipuler des séquences de données sur des observables. Ce sont des méthodes sur les observables qui transforment la source observable. Ils permettent un style de programmation fonctionnel pour gérer les collections. Dans notre exemple, nous avons utilisé l'opérateur map () pour filtrer les dépenses qui correspondent à la date transmise en tant que paramètre.

Vous remarquerez des lignes ondulées indiquant que vous devez importer des références pour le nouveau type et fonction que vous avez utilisés. Ajoutez les déclarations d'importation ci-dessous au fichier.

 import   { HttpClient }   de   "@ angular / common / http" ; 
 import   ] { Observable }   de   "rxjs" ; 
 importation   { carte }   de   "rxjs / operators "; 

Abonnement à Observables

Il est maintenant temps d'utiliser le service que vous avez créé dans la dernière section ✌️. Ouvrez src / app / home / home.component.ts et mettez à jour le constructeur et les lignes 18 et 19 avec le code ci-dessous:

 constructeur  ( dépensesService :  ExpenseService )   {
   this .  _expenseService  =  dépensesService ; 
} 

dépenses :  IExpense  [] ; 
currentMonthSpending  =   {} ; 
lastMonthSpending  =   {} ; 

Ce que vous avez fait a été de modifier les valeurs par défaut des propriétés currentMonthSpending et lastMonthSpending et de supprimer l'appel. à getExpenses () du constructeur. Vous vous demandez peut-être… pourquoi et comment obtiendrions-nous les données nécessaires? Des tâches telles que la récupération de données à partir d'un serveur distant peuvent prendre beaucoup de temps à exécuter et retarder ainsi l'initialisation du composant. C'est pourquoi il est préférable de garder le constructeur léger et d'effectuer des tâches d'initialisation complexes en dehors du constructeur. Nous allons mettre le code à récupérer et définir les propriétés dans le hook de cycle de vie ngOnInit . C'est dans la méthode que vous mettez du code qui effectue des initialisations complexes peu de temps après la construction. Angular a des hooks de cycle de vie qui s'exécutent dans une séquence particulière. Je parlerai plus en détail des crochets du cycle de vie dans un article ultérieur, mais vous pouvez en lire plus dans la documentation .

La méthode ngOnInit a été ajoutée par défaut lorsque la CLI a échafaudé la classe de composants. Ajoutez-y le code suivant.

 ngOnInit  ()   {
   const  mois  =   [
     "janvier" [19659014] "Février" 
     "Mars" 
     "Avril" 
     "Mai" 
     "Juin" [19659014] "juillet" 
     "août" 
     "septembre" 
     "octobre" 
     "novembre" [19659014] "décembre" 
  ] ; 

   const  thisMonth  =   nouveau   Date  () ; 
   const  lastMonth  =   nouveau   Date  (
    thisMonth .  getFullYear  () 
    thisMonth .  getMonth  ()   -   1 
  ) ; 

   this .  _expenseService . [19659197] getExpenses  ( this .  getPeriod  ( thisMonth ) ) .  abonnez-vous  (
    dépenses  =>   {
       ceci .  dépenses  =  dépenses ; 
    } 
    erreur  =>   {
      console .  journal  ( "Erreur lors de la récupération des dépenses" ) ; 
      console .  error  ( error ) ; 
    } 
  ) ; 

   this .  _expenseService
    .  getTotalSpending  ( this .  getPeriod  ( thisMonth ) ) 
    .  abonnez-vous  ] ( montant  =>   {
       ceci .  currentMonthSpending  =   {
        mois :  mois  [ thisMonth .  getMonth  () ] 
        montant
      } ; 
    } ) ; 

   ceci .  _expenseService
    .  getTotalSpending  ( this .  getPeriod  ( lastMonth ) ) 
    .  s'abonner  ] ( montant  =>   {
       ceci .  lastMonthSpending  =   {
        mois :  mois  [ lastMonth .  getMonth  () ] 
        montant
      } ; 
    } ) ; 
} 

Le code que vous avez ajouté appelle les méthodes ExpenseService getExpenses () et getTotalSpending () afin d'obtenir les dépenses du mois en cours et une somme des dépenses du mois en cours et du mois dernier. Ces méthodes renvoient des observables et, pour recevoir les valeurs, vous appelez .subscribe () sur l'observable résultant. Ce n'est que lorsque vous appelez la méthode subscribe que l'observable commence à traiter votre demande et commence à émettre des valeurs.

La méthode .subscribe () sur les observables prend jusqu'à trois arguments , avec chacun d'eux une fonction de gestionnaire:

  1. Le premier argument est une fonction qui doit être exécutée lorsque l'observable émet des valeurs pendant le traitement de l'opération asynchrone.
  2. Le deuxième argument est une fonction de gestionnaire d'erreur qui s'exécute s'il y a une erreur.
  3. Le troisième argument est une fonction qui est appelée lorsque l'observable est terminée, c'est-à-dire lorsque l'opération asynchrone est terminée.

Aux lignes 43 à 45, nous avons passé une fonction pour définir les dépenses propriété de la classe au résultat de l'appel de this._expenseService.getExpenses (date) . Vous vous demandez peut-être pourquoi nous avons défini this.penses au résultat d'une opération observable, car les données doivent arriver l'une après l'autre. En effet, les demandes HTTP sont des opérations asynchrones uniques où une demande est envoyée au serveur et le serveur répond une fois avec toutes les données demandées. Par conséquent, une seule valeur est émise et, par conséquent, l'affectation dépenses => {this.expenses = dépenses; } . C'est aussi la raison pour laquelle nous avons utilisé l'opérateur de carte comme nous l'avons fait dans la classe de service.

Afin de compléter notre code, nous allons ajouter une méthode supplémentaire à la classe. Cette méthode est utilisée pour transformer l'objet date en la forme que nous voulons pour l'application. Ajoutez la méthode ci-dessous à la classe:

   getPeriod  ( date :  Date )   {
     const  période  =  date .  à JSON  () .  split  ( "-" ) ; 
     retour  période  [ 0 ]   +   "-"   +  période  [ 1 ] ; 
  } 

C'est un habillage

Vous pouvez démarrer l'application en exécutant la commande ng serve -o et vous devriez voir les données affichées, et si vous ouvrez le panneau réseau dans votre navigateur, vous devrait voir la requête / réponse HTTP au fichier JSON.

Pour récapituler, un observable peut être décrit comme un tableau dont les éléments arrivent de manière asynchrone dans le temps, et vous pouvez vous abonner pour recevoir la valeur qu'il émet. Vous pouvez appliquer des opérateurs à un observable, qui peut transformer la valeur source en une forme différente et renvoyer la valeur transformée aux abonnés. Nous avons utilisé la méthode pipe () pour composer des opérateurs observables, comme vous l'avez vu dans l'exemple. Angular utilise des observables dans sa bibliothèque pour gérer les opérations asynchrones et le service HttpClient qui est utilisé pour les opérations HTTP pour renvoyer un objet observable.

Restez à l'écoute pour mon prochain message, qui se concentrera sur le routage dans un Application angulaire!

Le code de cet article peut être téléchargé à partir de GitHub . Il est contenu dans le dossier src-part-5 . Si vous avez des questions, n'hésitez pas à laisser un commentaire ou à me contacter sur Twitter .







Source link