Header Ads Widget

Ticker

6/recent/ticker-posts

Tutorial de Angular 9 por ejemplo: API REST CRUD y solicitudes HTTP GET con HttpClient

 En este tutorial de Angular 9, aprenderemos a construir una aplicación de ejemplo Angular 10/9 Ajax CRUD siguiendo todos los pasos requeridos desde la creación / simulación de una API REST, el scaffolding de un nuevo proyecto, la configuración de las API esenciales y finalmente la construcción y implementar su aplicación final en la nube.

Aprenda también a crear una aplicación de chat con TypeScript, Angular 9 y PubNub / Chatkit

## ¿Qué aprenderemos en este tutorial de Angular 9?

  • Aprenderemos por ejemplo cómo enviar solicitudes GET con cadenas de consulta de URL y parámetros y procesar respuestas HTTP desde servidores API REST en su aplicación Angular 9 usando Httplientpara obtener y consumir datos JSON, cómo manejar errores para errores HTTP usando RxJS throwError()catchError()operadores, cómo reintentar solicitudes HTTP fallidas en conexiones de red deficientes y cancelar solicitudes pendientes utilizando RxJS retry()takeUntil()operadores, y finalmente cómo implementar la aplicación en el alojamiento de Firebase utilizando las últimas funciones de Angular 8.3+.
  • También veremos cómo usar los servicios Angular y RxJS Observables, y aprenderemos cómo configurar Angular Material en nuestro proyecto y diseñar la interfaz de usuario con componentes de Material Design.
  • Veremos cómo usar la nueva ng deployfunción en Angular 8.3+ para implementar fácilmente su aplicación Angular 9 desde la línea de comandos al alojamiento de Firebase.

Se lanza Angular 9 y viene con varias características nuevas y mejoras, particularmente el nuevo renderizador Ivy.

Nota : Tenga en cuenta que estamos utilizando HttpClient, que es una versión mejorada de la API de cliente HTTP, disponible a partir de la versión Angular 4.3.0-rc.0 . El antiguo cliente HTTP no está disponible en Angular 9.

También puede ver cómo usar HttpClient con Angular 8/9 para crear una aplicación de noticias que obtenga datos JSON de una API REST de terceros en este tutorial .

A lo largo de este tutorial paso a paso de Angular 9, veremos un ejemplo práctico de CRUD de cómo usar el HttpClient que está disponible en el @angular/common/httppaquete para realizar solicitudes HTTP GET utilizando el get()método.

¿Qué cubriremos en este tutorial?

Cubriremos:

  • Cómo crear una API REST CRUD falsa y completa que funcione,
  • Cómo instalar Angular CLI v9,
  • Cómo crear un proyecto de Angular 9 usando Angular CLI,
  • Cómo configurar Angular Material y diseñar su aplicación con Material Design,
  • Cómo crear componentes angulares, enrutamiento y navegación entre ellos,
  • Cómo crear e inyectar servicios Angular,
  • Cómo enviar solicitudes HTTP GET a servidores usando HttpClient,
  • Cómo usar la clase HttpParams para agregar cadenas de consulta URL en su HttpRequest,
  • Cómo suscribirse y darse de baja de RxJS Observables devueltos por HttpClient,
  • Cómo manejar los errores HTTP usando los operadores throwError()catchError(),
  • Cómo reintentar solicitudes HTTP fallidas utilizando el retry()operador RxJS ,
  • Cómo darse de baja de RxJS Observables devueltos de los métodos HttpClient usando el takeUntil()operador cuando se concentran las solicitudes,
  • Cómo construir su aplicación para producción e implementarla en el alojamiento de Firebase usando el nuevo ng deploycomando disponible en Angular 8.3+

Los pasos de este tutorial

Los pasos de este tutorial de Angular 9 son los siguientes:

  • Paso 1: configuración de Angular CLI 9
  • Paso 2: inicializar un nuevo proyecto de ejemplo de Angular 9
  • Paso 3: Configuración de una API REST JSON (falsa)
  • Paso 4: configuración de Angular HttpClient v9 en nuestro proyecto de ejemplo
  • Paso 5: creación de componentes de Angular 9
  • Paso 6 - Agregar enrutamiento Angular 9
  • Paso 7: diseñar la interfaz de usuario con Angular Material v9
  • Paso 8: consumir la API JSON REST con Angular HttpClient v9
  • Paso 9: agregar el manejo de errores HTTP con RxJS catchError()yHttpClient
  • Paso 9: reintento de solicitudes HTTP fallidas con RxJS retry()yHttpClient
  • Paso 11: cancelar la suscripción a HttpClient Observables con RxJS takeUntil()
  • Paso 12: agregar parámetros de consulta de URL al método get () de HttpClient
  • Paso 13: obtener la respuesta HTTP completa con Angular HttpClient v9 / 10
  • Paso 14: Solicitud de una respuesta HTTP escrita con Angular HttpClient v9 / 10
  • Paso 15: compilar e implementar su aplicación Angular 9 en Firebase Hosting

Comencemos presentando Angular HttpClient, sus características y por qué usarlo.

¿Qué es Angular HttpClient?

Las aplicaciones front-end, creadas con marcos como Angular, se comunican con los servidores back-end a través de las API REST (que se basan en el protocolo HTTP) utilizando la XMLHttpRequestinterfaz o la fetch()API.

Angular HttpClient hace uso de la XMLHttpRequestinterfaz que admite navegadores modernos y heredados.

El HttpClient está disponible en el @angular/common/httppaquete y tiene una interfaz API simplificada y características poderosas como facilidad de prueba, objetos de solicitud y respuesta escritos, interceptores de solicitud y respuesta, API reactivas con RxJS Observables y manejo de errores optimizado.

¿Por qué Angular HttpClient?

El HttpClientservicio integrado ofrece muchas ventajas a los desarrolladores de Angular:

  • HttpClient facilita el envío y procesamiento de solicitudes y respuestas HTTP,
  • HttpClient tiene muchas características integradas para implementar unidades de prueba,
  • HttpClient hace uso de RxJS Observables para manejar operaciones asincrónicas en lugar de Promesas que simplifican las tareas comunes de desarrollo web como
  • - La ocultación de solicitudes HTTP,
  • - Escuchar la progresión de las operaciones de descarga y carga de archivos ,
  • - Fácil manejo de errores,
  • - Reintentar solicitudes HTTP fallidas, etc.

Ahora, después de presentar HttpClient, procedamos a construir nuestra aplicación de ejemplo comenzando con los requisitos previos necesarios para completar con éxito nuestro tutorial de Angular 9.

Prerrequisitos

Antes de comenzar, necesita algunos requisitos previos:

  • Conocimientos básicos de TypeScript. En particular, la familiaridad con conceptos orientados a objetos como clases y decoradores de TypeScript.
  • Una máquina de desarrollo local con Node 10+ , junto con NPM 6+ instalado. La CLI de Angular requiere un nodo como la mayoría de las herramientas frontend en la actualidad. Simplemente puede ir a la página de descargas del sitio web oficial y descargar los binarios para su sistema operativo. También puede consultar las instrucciones específicas de su sistema sobre cómo instalar Node usando un administrador de paquetes. Sin embargo, la forma recomendada es usar NVM - Node Version Manager - un script bash compatible con POSIX para administrar múltiples versiones activas de Node.js.

Nota : Si no desea instalar un entorno local para el desarrollo de Angular pero aún desea probar el código en este tutorial, puede usar Stackblitz , un IDE en línea para el desarrollo de frontend que puede usar para crear un proyecto Angular compatible con Angular. CLI.

Si usted tiene los requisitos anteriores, usted está listo para los siguientes pasos de nuestra angular 9 tutorial que le enseñará por ejemplo cómo utilizar angular HttpClient para enviar peticiones HTTP GET para traer los datos JSON y los diversos RxJS operadores tales como catchError()tap()retry(), y takeUntil()para implementar funciones avanzadas como el manejo de errores, reintentar solicitudes HTTP fallidas y cancelar solicitudes pendientes.

En los primeros pasos de nuestro tutorial, veremos cómo instalar Angular CLI 9 y crear un proyecto de ejemplo desde cero.

Paso 1: configuración de Angular CLI v9

En este paso, instalaremos la última versión de Angular CLI 9 (en el momento de escribir este tutorial).

Nota : estas instrucciones también son válidas para Angular 8.

CLI angular

Angular CLI es la herramienta oficial para inicializar y trabajar con proyectos Angular. Para instalarlo, abra una nueva interfaz de línea de comandos y ejecute el siguiente comando:

$ npm install -g @angular/cli

En el momento de escribir este tutorial, angular / cli v9 estará instalado en su sistema.

Tenga en cuenta que hasta que Angular 9 se @nextlance oficialmente, puede usar la etiqueta para instalar la última versión preliminar:

$ npm install -g @angular/cli@next

Si ejecuta el ng versioncomando, debería obtener un resultado similar:

Angular CLI: 9.0.0-next.0
Node: 12.14.0
OS: linux x64

Angular: 
... 
Ivy Workspace: 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.900.0-next.0
@angular-devkit/core         9.0.0-next.0
@angular-devkit/schematics   9.0.0-next.0
@angular/cli                 9.0.0-next.0
@schematics/angular          9.0.0-next.0
@schematics/update           0.900.0-next.0
rxjs                         6.5.4

En el siguiente paso, aprenderemos cómo inicializar un nuevo proyecto de ejemplo desde la línea de comandos.

Paso 2: inicialización de un nuevo proyecto de ejemplo de Angular 9/9

En este paso, procederemos a crear nuestro proyecto de ejemplo. Regrese a su interfaz de línea de comandos y ejecute los siguientes comandos:

$ cd ~
$ ng new angular-httpclient-example

La CLI le hará un par de preguntas: ¿ Si desea agregar enrutamiento angular? Escriba y para Sí y ¿Qué formato de hoja de estilo le gustaría usar? Elija CSS .

Esto le indicará a la CLI que configure automáticamente el enrutamiento en nuestro proyecto, por lo que solo necesitaremos agregar las rutas para nuestros componentes para implementar la navegación en nuestra aplicación.

Si ejecuta el ng versioncomando dentro de la carpeta de su proyecto, debería obtener un resultado similar:

Angular CLI: 9.0.2
Node: 12.14.0
OS: linux x64

Angular: 9.0.1
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.2
@angular-devkit/build-angular     0.900.2
@angular-devkit/build-optimizer   0.900.2
@angular-devkit/build-webpack     0.900.2
@angular-devkit/core              9.0.2
@angular-devkit/schematics        9.0.2
@angular/cli                      9.0.2
@ngtools/webpack                  9.0.2
@schematics/angular               9.0.2
@schematics/update                0.900.2
rxjs                              6.5.4
typescript                        3.7.5
webpack                           4.41.2

A continuación, navegue hasta la carpeta de su proyecto y ejecute el servidor de desarrollo local usando los siguientes comandos:

$ cd angular-httpclient-example
$ ng serve    

Un servidor de desarrollo local comenzará a escuchar la http://localhost:4200/dirección. Servicio CLI Ng angular

Abra su navegador web y navegue hasta la http://localhost:4200/dirección para ver su aplicación en funcionamiento. Esta es una captura de pantalla en este punto:

Proyecto Angular 9

Ahora debe dejar el servidor de desarrollo en ejecución e iniciar una nueva interfaz de línea de comandos para ejecutar los comandos CLI de los siguientes pasos.

En el siguiente paso, aprenderemos cómo crear una API REST JSON falsa que consumiremos en nuestra aplicación de ejemplo Angular.

Paso 3: Configuración de una API REST JSON (falsa)

Antes de proceder a desarrollar nuestra aplicación Angular, necesitaremos preparar una API REST JSON que podamos consumir usando HttpClient.

También podemos consumir o obtener datos JSON de servidores API REST de terceros, pero en este ejemplo, elegimos crear una API REST falsa. Consulte este tutorial para ver un ejemplo real de API REST. En lo que respecta a Angular, no hay diferencia entre consumir API REST falsas o reales.

Como se dijo, puede usar un servicio API externo, crear un servidor API REST real o crear una API falsa usando json-serverEn este ejemplo usaremos el último enfoque.

Así que dirígete a una nueva interfaz de línea de comandos y comienza instalando json-serverdesde npm en tu proyecto:

$ cd ~/angular-httpclient-example
$ npm install --save json-server 

A continuación, cree una servercarpeta en la carpeta raíz de su proyecto Angular:

$ mkdir server
$ cd server

En la servercarpeta, cree un database.jsonarchivo y agregue el siguiente objeto JSON:

{
    "products": []
}

Este archivo JSON actuará como una base de datos para su servidor de API REST. Simplemente puede agregar algunos datos para que los sirva su API REST o usar Faker.js para generar automáticamente cantidades masivas de datos falsos realistas.

Regrese a su línea de comandos, navegue hacia atrás desde la servercarpeta e instale Faker.jsdesde npm usando el siguiente comando:

$ cd ..
$ npm install faker --save

En el momento de crear este ejemplo, se instalará faker v4.1.0 .

Ahora, cree un generate.jsarchivo y agregue el siguiente código:

var faker = require('faker');

var database = { products: []};

for (var i = 1; i<= 300; i++) {
  database.products.push({
    id: i,
    name: faker.commerce.productName(),
    description: faker.lorem.sentences(),
    price: faker.commerce.price(),
    imageUrl: "https://source.unsplash.com/1600x900/?product",
    quantity: faker.random.number()
  });
}

console.log(JSON.stringify(database));

Primero importamos faker, luego definimos un objeto con una matriz vacía para productos. A continuación, ingresamos un bucle for para crear 300 entradas falsas utilizando métodos falsos como faker.commerce.productName()para generar nombres de productos. Consulta todos los métodos disponibles . Finalmente, convertimos el objeto de la base de datos en una cadena y lo registramos en la salida estándar.

A continuación, agregue los scripts generateserveral package.jsonarchivo:

  "scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build",
    "test": "ng test",
    "lint": "ng lint",
    "e2e": "ng e2e",
    "generate": "node ./server/generate.js > ./server/database.json",
    "server": "json-server --watch ./server/database.json"
  },

A continuación, regrese a su interfaz de línea de comandos y ejecute el script de generación con el siguiente comando:

$ npm run generate

Finalmente, ejecute el servidor de la API REST ejecutando el siguiente comando:

$ npm run server

Ahora puede enviar solicitudes HTTP al servidor como cualquier servidor API REST típico. Su servidor estará disponible en la http://localhost:3000/dirección.

Servidor de API REST

Estos son los puntos finales de API que podremos usar a través de nuestro servidor de API REST JSON:

  • GET /products para conseguir los productos,
  • GET /products/<id> para obtener un solo producto por id,
  • POST /products para crear un nuevo producto,
  • PUT /products/<id> para actualizar un producto por id,
  • PATCH /products/<id> para actualizar parcialmente un producto por id,
  • DELETE /products/<id> para eliminar un producto por id.

Puede utilizar _page_limitparámetros para obtener datos paginados. En la Linkcabecera que obtendrá firstprevnextlastenlaces.

Por ejemplo:

GET /products?_page=1para obtener la primera página de datos, GET /products?_page=1&_limit=5para obtener los primeros cinco productos de la primera página de datos.

Nota : puede utilizar otras funciones como filtros, clasificación y ordenación. Para obtener más información, consulte los documentos .

Deje el servidor de la API REST de JSON en ejecución y abra una nueva interfaz de línea de comandos para escribir los comandos de los siguientes pasos.

Como resumen de lo que hemos hecho: instalamos Angular CLI e inicializamos un nuevo proyecto basado en la última versión de Angular 9. Luego, creamos una API REST json-serverbasada en un archivo JSON. En el siguiente paso de nuestro tutorial de Angular 9, aprenderemos cómo configurar HttpClienten nuestro proyecto de Angular 9.

Paso 4: configuración de Angular 9 HttpClient en nuestro proyecto de ejemplo

En este paso, procederemos a configurar el HttpClientmódulo en nuestro ejemplo.

HttpClientvive en un módulo Angular separado , por lo que necesitaremos importarlo en nuestro módulo de aplicación principal antes de que podamos usarlo.

Abra su proyecto de ejemplo con un editor de código o IDE. Usaré Visual Studio Code .

A continuación, abra el src/app/app.module.tsarchivo, impórtelo HttpClientModuley agréguelo a la importsmatriz del módulo de la siguiente manera:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Eso es todo, ahora estamos listos para usar el HttpClientservicio en nuestro proyecto, pero antes de eso necesitamos crear un par de componentes: el hogar y los componentes. Esto es lo que aprenderemos a hacer en el siguiente paso.

Paso 5: creación de componentes de Angular 9

En este paso, procederemos a crear los componentes angulares que controlan la interfaz de usuario de nuestra aplicación.

Regrese a una nueva interfaz de línea de comandos y ejecute el siguiente comando:

$ cd ~/angular-httpclient-example
$ ng generate component home

Esta es la salida del comando:

CREATE src/app/home/home.component.html (19 bytes)
CREATE src/app/home/home.component.spec.ts (614 bytes)
CREATE src/app/home/home.component.ts (261 bytes)
CREATE src/app/home/home.component.css (0 bytes)
UPDATE src/app/app.module.ts (467 bytes)

La CLI creó cuatro archivos para el componente y lo agregó a la declarationsmatriz en el src/app/app.module.tsarchivo.

A continuación, creemos el componente about usando el siguiente comando:

$ ng generate component about

A continuación, abra src/app/about/about.component.htmly agregue el siguiente código:

<p style="padding: 13px;">
An Angular 9 example application that demonstrates how to use HttpClient to consume REST APIs
</p>

Actualizaremos el componente de inicio en los siguientes pasos.

En el siguiente paso de nuestro tutorial de Angular 9, agregaremos estos componentes al enrutador.

Paso 6 - Agregar enrutamiento Angular 9

En este paso, procederemos a agregar enrutamiento a nuestro ejemplo.

Regrese al src/app/app-routing.module.tsarchivo, que fue creado automáticamente por Angular CLI para la configuración de enrutamiento, e importe los componentes y luego agregue las rutas de la siguiente manera:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';


const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full'},
  { path: 'home', component: HomeComponent },
  { path: 'about', component: AboutComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Primero importamos los componentes de inicio y about, luego agregamos tres rutas, incluida una ruta para redirigir la ruta vacía al componente de inicio, de modo que cuando el usuario visite la aplicación, será redirigido a la página de inicio.

En el siguiente paso de nuestro ejemplo, configuraremos Material angular en nuestro proyecto para diseñar nuestra interfaz de usuario.

Paso 7: diseñar la interfaz de usuario con Angular Material v9

En este paso de nuestro tutorial de Angular 9, procederemos a agregar material angular a nuestro proyecto y diseñar la interfaz de usuario de nuestra aplicación.

Angular Material proporciona componentes de Material Design que permiten a los desarrolladores crear interfaces de usuario profesionales. Configurar Angular Material en nuestro proyecto es mucho más fácil ahora con el nuevo ng addcomando de Angular CLI v7 +.

Regrese a su interfaz de línea de comandos y ejecute el siguiente comando desde la raíz de su proyecto:

$ ng add @angular/material

Se le pedirá que elija un tema, elija Indigo / Pink .

Para las otras opciones, ¿ configurar HammerJS para el reconocimiento de gestos? y ¿ Configurar animaciones del navegador para Angular Material? Simplemente presione Entrar en su teclado para elegir las respuestas predeterminadas.

A continuación, abra el src/styles.cssarchivo y agregue un tema:

@import "~@angular/material/prebuilt-themes/indigo-pink.css";

Cada componente de Angular Material tiene un módulo separado que debe importar antes de poder usar el componente. Abra el src/app/app.module.tsarchivo y agregue las siguientes importaciones:

import { MatToolbarModule,
  MatIconModule,
  MatCardModule,
  MatButtonModule,
  MatProgressSpinnerModule } from '@angular/material';

Importamos los siguientes módulos:

  • MatToolbar que proporciona un contenedor para encabezados, títulos o acciones.
  • MatCard que proporciona un contenedor de contenido para texto, fotos y acciones en el contexto de un solo tema.
  • MatButton que proporciona un elemento nativo <button><a>mejorado con el estilo de Material Design y las ondas de tinta.
  • MatProgressSpinner que proporciona un indicador circular de progreso y actividad.

A continuación, debe incluir estos módulos en la importsmatriz:

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    AboutComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    BrowserAnimationsModule,
    MatToolbarModule,
    MatIconModule,
    MatButtonModule,
    MatCardModule,
    MatProgressSpinnerModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

A continuación, abra el src/app/app.component.htmlarchivo y actualícelo de la siguiente manera:

<mat-toolbar color="primary">
  <h1>
    ngStore 
  </h1>
  <button mat-button routerLink="/">Home</button>
  <button mat-button routerLink="/about">About</button>

</mat-toolbar>

<router-outlet></router-outlet>

Creamos el shell de nuestra aplicación que contiene una barra superior con dos botones de navegación hacia el inicio y sobre los componentes.

Como resumen de lo que hicimos hasta este punto de nuestro tutorial: configuramos HttpClient y Angular Material v9 en nuestro proyecto, creamos el inicio y los componentes y configuramos el enrutamiento, y finalmente agregamos el shell de nuestra aplicación que contiene una barra superior con navegación.

En el siguiente paso de nuestro tutorial, aprenderemos cómo obtener los datos JSON de nuestro servidor API REST usando HttpClientv9.

También lea más de 3 formas de integrar Bootstrap con Angular y cómo diseñar interfaces de usuario de Angular 10 con Bootstrap 4 .

Paso 8: consumir la API JSON REST con Angular HttpClient 9

En este paso, procederemos a consumir datos JSON de nuestro servidor API REST en nuestra aplicación de ejemplo.

Necesitaremos crear un servicio Angular para encapsular el código que se ocupa de consumir datos del servidor de la API REST.

Un servicio es un singleton que puede ser inyectado por otros servicios y componentes usando la inyección de dependencia Angular.

En ingeniería de software, la inyección de dependencias es una técnica mediante la cual un objeto proporciona las dependencias de otro objeto. Fuente

Ahora, generemos un servicio Angular que interactúe con la API JSON REST. Regrese a su interfaz de línea de comandos y ejecute el siguiente comando:

$ ng generate service data

A continuación, abra el src/app/data.service.tsarchivo, importe e inyecte de la HttpClientsiguiente manera:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  private REST_API_SERVER = "http://localhost:3000";

  constructor(private httpClient: HttpClient) { }
}

Importamos e inyectamos el HttpClientservicio como una httpClientinstancia privada También definimos la REST_API_SERVERvariable que contiene la dirección de nuestro servidor API REST.

A continuación, agregue un sendGetRequest()método que envíe una solicitud GET al punto final de la API REST para recuperar datos JSON:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class DataService {

  private REST_API_SERVER = "http://localhost:3000";

  constructor(private httpClient: HttpClient) { }

  public sendGetRequest(){
    return this.httpClient.get(this.REST_API_SERVER);
  }
}

El método simplemente invoca el get()método de HttpClientenviar solicitudes GET al servidor API REST.

A continuación, ahora necesitamos utilizar este servicio en nuestro componente doméstico. Abra el src/app/home/home.component.tsarchivo, importe e inyecte el servicio de datos de la siguiente manera:

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  products = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {

    this.dataService.sendGetRequest().subscribe((data: any[])=>{
      console.log(data);
      this.products = data;
    })  
  }

}

Importamos e inyectamos DataServicecomo una dataServiceinstancia privada a través del constructor del componente.

A continuación, definimos una productsvariable y llamamos al sendGetRequest()método del servicio para obtener datos del servidor de la API JSON REST.

Dado que el sendGetRequest()método devuelve el valor de retorno del HttpClient.get()método que es un Observable RxJS, nos suscribimos al Observable devuelto para enviar realmente la solicitud HTTP GET y procesar la respuesta HTTP.

Cuando se reciben los datos, los agregamos en la productsmatriz.

A continuación, abra el src/app/home/home.component.htmlarchivo y actualícelo de la siguiente manera:

<div style="padding: 13px;">
    <mat-spinner *ngIf="products.length === 0"></mat-spinner>

    <mat-card *ngFor="let product of products" style="margin-top:10px;">
        <mat-card-header>
            <mat-card-title>{{product.name}}</mat-card-title>
            <mat-card-subtitle>{{product.price}} $/ {{product.quantity}}
            </mat-card-subtitle>
        </mat-card-header>
        <mat-card-content>
            <p>
                {{product.description}}
            </p>
            <img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" />
        </mat-card-content>
        <mat-card-actions>
      <button mat-button> Buy product</button>
    </mat-card-actions>
    </mat-card>
</div>

Usamos el <mat-spinner>componente para mostrar una ruleta de carga cuando la longitud de la productsmatriz es igual a cero, es decir, antes de que no se reciban datos del servidor API REST.

A continuación, se repiten a lo largo de la productsmatriz que utiliza ngFory se utiliza una tarjeta de materiales para visualizar el namepricequantitydescriptionimagede cada producto.

Esta es una captura de pantalla de la página de inicio después de que se obtienen los datos JSON:

Ejemplo de Angular 9

A continuación, veremos cómo agregar el manejo de errores a nuestro servicio.

Paso 9: agregar el manejo de errores HTTP con RxJS catchError()yHttpClient

En este paso, procederemos a agregar el manejo de errores en nuestra aplicación de ejemplo.

Los métodos HttpClient de Angular se pueden usar fácilmente con el catchError()operador de RxJS, ya que devuelven Observables, a través del pipe()método para detectar y manejar errores. Simplemente necesitamos definir un método para manejar errores dentro de su servicio.

Hay dos tipos de errores en las aplicaciones de front-end:

  • Errores del lado del cliente, como problemas de red y sintaxis de JavaScript y errores de tipo. Estos errores devuelven ErrorEventobjetos.
  • Errores del lado del servidor, como errores de código en el servidor y errores de acceso a la base de datos. Estos errores devuelven respuestas de error HTTP.

Como tal, simplemente necesitamos verificar si un error es una instancia de ErrorEventpara obtener el tipo de error para poder manejarlo adecuadamente.

Ahora, veamos esto con un ejemplo. Abra el src/app/data.service.tsarchivo y actualícelo en consecuencia:

import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from "@angular/common/http";

import {  throwError } from 'rxjs';
import { retry, catchError } from 'rxjs/operators';


@Injectable({
  providedIn: 'root'
})
export class DataService {

  private REST_API_SERVER = "http://localhost:3000/products";

  constructor(private httpClient: HttpClient) { }

  handleError(error: HttpErrorResponse) {
    let errorMessage = 'Unknown error!';
    if (error.error instanceof ErrorEvent) {
      // Client-side errors
      errorMessage = `Error: ${error.error.message}`;
    } else {
      // Server-side errors
      errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    window.alert(errorMessage);
    return throwError(errorMessage);
  }

  public sendGetRequest(){
    return this.httpClient.get(this.REST_API_SERVER).pipe(catchError(this.handleError));
  }
}

Como puede ver, esto debe hacerse para cada servicio en su aplicación, lo cual está bien para nuestro ejemplo, ya que solo contiene un servicio, pero una vez que su aplicación comienza a crecer con muchos servicios que pueden arrojar errores, debe usar mejores soluciones en lugar de utilizando el handleErrormétodo para cada servicio que es propenso a errores. Una solución es manejar errores globalmente en su aplicación Angular usando interceptores HttpClient .

Esta es una captura de pantalla de un error en la consola si no se puede acceder al servidor:

Ejemplo de error de HttpClient angular

En el siguiente paso, veremos cómo mejorar nuestro servicio de datos volviendo a intentar enviar automáticamente las solicitudes HTTP fallidas.

Paso 10: reintento de solicitudes HTTP fallidas con RxJS retry()yHttpClient

En este paso de nuestro tutorial de Angular 9, veremos cómo usar el retry()operador de RxJS con HttpClient para volver a suscribirse automáticamente al Observable devuelto, lo que da como resultado el reenvío de las solicitudes HTTP fallidas.

En muchos casos, los errores son temporales y se deben a las malas condiciones de la red, por lo que simplemente intentarlo de nuevo hará que desaparezcan automáticamente. Por ejemplo, en los dispositivos móviles las interrupciones de la red son frecuentes, por lo que si el usuario vuelve a intentarlo, puede obtener una respuesta exitosa. En lugar de permitir que los usuarios vuelvan a intentarlo manualmente, veamos cómo hacerlo automáticamente en nuestra aplicación de ejemplo.

La biblioteca RxJS proporciona varios operadores de reintento. Entre ellos se encuentra el retry()operador que le permite volver a suscribirse automáticamente a un RxJS Observable un número específico de veces. Volver a suscribirse al Observable devuelto desde un método HttpClient tiene el efecto de reenviar la solicitud HTTP al servidor para que los usuarios no necesiten repetir la operación o recargar la aplicación.

Puede usar el retry()operador RxJS canalizándolo (usando el pipe()método) en el Observable devuelto por el método HttpClient antes del controlador de errores.

Vaya al src/app/data.service.tsarchivo e importe el retry()operador:

import { retry, catchError } from 'rxjs/operators';

A continuación, actualice el sendGetRequest()método de la siguiente manera:

  public sendGetRequest(){
    return this.httpClient.get(this.REST_API_SERVER).pipe(retry(3), catchError(this.handleError));
  }

Esto volverá a intentar enviar la solicitud HTTP fallida tres veces.

En el siguiente paso, veremos cómo cancelar la suscripción a RxJS Observables en nuestro componente de inicio de ejemplo.

Paso 11: cancelar la suscripción a HttpClient Observables con RxJS takeUntil()

En este paso de nuestro tutorial de Angular 9, aprenderemos por qué necesitamos y cómo cancelar la suscripción a Observables en nuestro código usando el takeUntil()operador.

En primer lugar, ¿necesita darse de baja de los Observables devueltos por los HttpClientmétodos?

En general, debe cancelar la suscripción manualmente de cualquier RxJS Observables suscrito en sus componentes de Angular para evitar pérdidas de memoria, pero en el caso de HttpClient, Angular lo maneja automáticamente al cancelar la suscripción cuando se recibe la respuesta HTTP. Sin embargo, hay algunos casos en los que necesita darse de baja manualmente, por ejemplo, para cancelar las solicitudes pendientes cuando los usuarios están a punto de abandonar el componente.

Simplemente podemos llamar al unsubscribe()método desde el Subscriptionobjeto devuelto por el subscribe()método en el ngOnDestroy()método del ciclo de vida del componente para cancelar la suscripción del Observable.

También hay una mejor manera de cancelar la suscripción o completar Observables utilizando el takeUntil()operador.

El operador takeUntil () emite los valores emitidos por la fuente Observable hasta que un notificador Observable emite un valor.

Veamos cómo usar este operador para completar Observables cuando se destruye el componente.

Consulte Cómo cancelar / cancelar la suscripción de todas las solicitudes HTTP pendientes angular 4+ .

Abra el src/app/home/home.component.tsarchivo y actualícelo de la siguiente manera:

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DataService } from '../data.service';
import {  takeUntil } from 'rxjs/operators';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit, OnDestroy {

  products = [];
  destroy$: Subject<boolean> = new Subject<boolean>();

  constructor(private dataService: DataService) { }

  ngOnInit() {

    this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((data: any[])=>{
      console.log(data);
      this.products = data;
    })  
  }
  ngOnDestroy() {
    this.destroy$.next(true);
    // Unsubscribe from the subject
    this.destroy$.unsubscribe();
  }

}

Primero importamos la OnDestroyinterfaz Subjecty el takeUntil()operador. A continuación, implementamos la OnDestroyinterfaz y agregamos el ngOnDestroy() enlace del ciclo de vida al componente.

A continuación, creamos una instancia Subjectque puede emitir valores booleanos (el tipo de valor realmente no importa en este ejemplo) que se usará como notificador del takeUntil()operador.

A continuación, en el ngOnInit()enlace del ciclo de vida, llamamos al sendGetRequest()de nuestro servicio de datos y llamamos al pipe()método del Observable devuelto para canalizar al takeUnitl()operador y finalmente suscribirse al Observable combinado. En el cuerpo del subscribe()método, agregamos la lógica para colocar los datos obtenidos de la respuesta HTTP en la productsmatriz.

El takeUntil()operador permite que un Observable notificado emita valores hasta que se emita un valor de un Observable notificador.

Cuando Angular destruye un componente, llama al ngOnDestroy()método del ciclo de vida que, en nuestro caso, llama al next()método para emitir un valor para que RxJS complete todos los Observables suscritos.

Eso es. En este paso, hemos agregado la lógica para cancelar cualquier solicitud HTTP pendiente al cancelar la suscripción del Observable devuelto en caso de que el usuario decida navegar fuera del componente antes de que se reciba la respuesta HTTP.

También lea cómo darse de baja de los sujetos RxJS cuando se destruye el componente angular

En el siguiente paso de nuestro tutorial de Angular 9, veremos cómo usar los parámetros de consulta de URL con el get()método de HttpClient.

Paso 12: agregar parámetros de consulta de URL al get()método HttpClient

En este paso, comenzaremos a agregar la lógica para implementar la paginación en nuestra aplicación de ejemplo. Veremos cómo usar los parámetros de consulta de URL a través de fromStringyHttpParams cómo proporcionar los valores apropiados para los parámetros _page_limitdel /productspunto final de nuestro servidor de API JSON REST para obtener datos paginados.

Abra el src/app/data.service.tsarchivo y comience agregando lo siguiente para la importación HttpParams:

import { HttpClient, HttpErrorResponse, HttpParams } from "@angular/common/http";

A continuación, actualice el sendGetRequest()método de la siguiente manera:

  public sendGetRequest(){
    // Add safe, URL encoded_page parameter 
    const options = { params: new HttpParams({fromString: "_page=1&_limit=20"}) };
    return this.httpClient.get(this.REST_API_SERVER, options).pipe(retry(3), catchError(this.handleError));
  }

Usamos HttpParamsfromStringpara crear parámetros de consulta HTTP a partir de la _page=1&_limit=20cadena. Esto indica que devuelve la primera página de 20 productos.

Ahora sendGetRequest()se utilizará para recuperar la primera página de datos. La respuesta HTTP recibida contendrá un encabezado de enlace con información sobre el primer, el anterior, el siguiente y el último enlace de las páginas de datos.

En el encabezado del enlace, obtendrá los enlaces primero, anterior, siguiente y último. En el siguiente paso, veremos cómo extraer estos enlaces de paginación analizando las respuestas HTTP completas.

Paso 13: obtener la respuesta HTTP completa con Angular HttpClient 9

En este paso, procederemos a implementar la lógica para recuperar la información de paginación del encabezado del enlace contenido en la respuesta HTTP recibida del servidor de la API JSON REST.

De forma predeterminada, HttpClient solo proporciona el cuerpo de la respuesta, pero en nuestro caso necesitamos analizar el encabezado del enlace para los enlaces de paginación, por lo HttpClientque debemos decir que queremos el completo HttpResponseusando la observeopción.

El encabezado de enlace en HTTP permite al servidor señalar a un cliente interesado a otro recurso que contiene metadatos sobre el recurso solicitado. Wikipedia

Vaya al src/app/data.service.tsarchivo e importe el tap()operador RxJS :

import { retry, catchError, tap } from 'rxjs/operators';

A continuación, defina las siguientes variables de cadena:

  public first: string = "";
  public prev: string = "";
  public next: string = "";
  public last: string = "";

A continuación, defina el parseLinkHeader()método que analiza el encabezado del enlace y complete las variables anteriores en consecuencia:

  parseLinkHeader(header) {
    if (header.length == 0) {
      return ;
    }

    let parts = header.split(',');
    var links = {};
    parts.forEach( p => {
      let section = p.split(';');
      var url = section[0].replace(/<(.*)>/, '$1').trim();
      var name = section[1].replace(/rel="(.*)"/, '$1').trim();
      links[name] = url;

    });

    this.first  = links["first"];
    this.last   = links["last"];
    this.prev   = links["prev"];
    this.next   = links["next"]; 
  }

A continuación, actualice el sendGetRequest()siguiente:

  public sendGetRequest(){
    // Add safe, URL encoded _page and _limit parameters 

    return this.httpClient.get(this.REST_API_SERVER, {  params: new HttpParams({fromString: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {
      console.log(res.headers.get('Link'));
      this.parseLinkHeader(res.headers.get('Link'));
    }));
  }

Agregamos la observeopción con el responsevalor en el parámetro de opciones del get()método para que podamos tener la respuesta HTTP completa con encabezados. A continuación, usamos el tap()operador RxJS para analizar el encabezado del enlace antes de devolver el Observable final.

Dado sendGetRequest()que ahora está devolviendo un Observable con una respuesta HTTP completa, necesitamos actualizar el componente de inicio, así que abra el src/app/home/home.component.tsarchivo e importe de la HttpResponsesiguiente manera:

import { HttpResponse } from '@angular/common/http';

A continuación, actualice el subscribe()método de la siguiente manera:

  ngOnInit() {

    this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>)=>{
      console.log(res);
      this.products = res.body;
    })  
  }

Ahora podemos acceder a los datos del bodyobjeto de la respuesta HTTP recibida.

A continuación, vuelva al archivo src / app / data.service.ts y agregue el siguiente método:

  public sendGetRequestToUrl(url: string){
    return this.httpClient.get(url, { observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {
      console.log(res.headers.get('Link'));
      this.parseLinkHeader(res.headers.get('Link'));

    }));
  }

Este método es similar a sendGetRequest()excepto que toma la URL a la que necesitamos enviar una solicitud HTTP GET.

Regrese al src/app/home/home.component.tsarchivo y agregue definir los siguientes métodos:

  public firstPage() {
    this.products = [];
    this.dataService.sendGetRequestToUrl(this.dataService.first).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
      console.log(res);
      this.products = res.body;
    })
  }
  public previousPage() {

    if (this.dataService.prev !== undefined && this.dataService.prev !== '') {
      this.products = [];
      this.dataService.sendGetRequestToUrl(this.dataService.prev).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
        console.log(res);
        this.products = res.body;
      })
    }

  }
  public nextPage() {
    if (this.dataService.next !== undefined && this.dataService.next !== '') {
      this.products = [];
      this.dataService.sendGetRequestToUrl(this.dataService.next).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
        console.log(res);
        this.products = res.body;
      })
    }
  }
  public lastPage() {
    this.products = [];
    this.dataService.sendGetRequestToUrl(this.dataService.last).pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<any>) => {
      console.log(res);
      this.products = res.body;
    })
  }

Finalmente, agregue abrir el src/app/home/home.component.htmlarchivo y actualice la plantilla de la siguiente manera:

<div style="padding: 13px;">
    <mat-spinner *ngIf="products.length === 0"></mat-spinner>

    <mat-card *ngFor="let product of products" style="margin-top:10px;">
        <mat-card-header>
            <mat-card-title>#{{product.id}} {{product.name}}</mat-card-title>
            <mat-card-subtitle>{{product.price}} $/ {{product.quantity}}
            </mat-card-subtitle>
        </mat-card-header>
        <mat-card-content>
            <p>
                {{product.description}}
            </p>
            <img style="height:100%; width: 100%;" src="{{ product.imageUrl }}" />
        </mat-card-content>
        <mat-card-actions>
      <button mat-button> Buy product</button>
    </mat-card-actions>
    </mat-card>

</div>
<div>
    <button (click) ="firstPage()" mat-button> First</button>
    <button (click) ="previousPage()" mat-button> Previous</button>
    <button (click) ="nextPage()" mat-button> Next</button>
    <button (click) ="lastPage()" mat-button> Last</button>
</div>

Esta es una captura de pantalla de nuestra aplicación: 

Paso 14: solicitud de una respuesta HTTP escrita con Angular HttpClient 9

En este paso, veremos cómo usar respuestas HTTP escritas en nuestra aplicación de ejemplo.

Angular HttpClient le permite especificar el tipo de objeto de respuesta en el objeto de solicitud, lo que hace que consumir la respuesta sea más fácil y directo. Esto también habilita la aserción de tipos durante el tiempo de compilación.

Comencemos por definir un tipo personalizado usando una interfaz TypeScript con las propiedades requeridas.

Regrese a su interfaz de línea de comandos y ejecute el siguiente comando desde la raíz de su proyecto:

$ ng generate interface  product

A continuación, abra el src/app/product.tsarchivo y actualícelo de la siguiente manera:

export interface Product {
    id: number;
    name: string;
    description: string;
    price: number;
    quantity: number;
    imageUrl: string;
}

A continuación, especifique la Productinterfaz como HttpClient.get()parámetro de tipo de llamada en el servicio de datos. Regrese al src/app/data.service.tsarchivo e importe la Productinterfaz:

import { Product } from './product';

Próximo:

  public sendGetRequest(){

    return this.httpClient.get<Product[]>(this.REST_API_SERVER, {  params: new HttpParams({fromString: "_page=1&_limit=20"}), observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {
      console.log(res.headers.get('Link'));
      this.parseLinkHeader(res.headers.get('Link'));

    }));
  }

  public sendGetRequestToUrl(url: string){
    return this.httpClient.get<Product[]>(url, { observe: "response"}).pipe(retry(3), catchError(this.handleError), tap(res => {
      console.log(res.headers.get('Link'));
      this.parseLinkHeader(res.headers.get('Link'));

    }));
  }

A continuación, abra el src/app/home/home.component.tsarchivo e importe la Productinterfaz:

import { Product } from '../product';

A continuación, cambie el tipo de productsmatriz de la siguiente manera:

export class HomeComponent implements OnInit, OnDestroy {

  products: Product[] = [];

A continuación, cambie el tipo de respuesta HTTP en la sendGetRequest()llamada:

  ngOnInit() {

    this.dataService.sendGetRequest().pipe(takeUntil(this.destroy$)).subscribe((res: HttpResponse<Product[]>) => {
      console.log(res);
      this.products = res.body;
    })
  }

También es necesario hacer lo mismo para los demás firstPage()previousPage()nextPage()lastPage()métodos.

Paso 15: compilar e implementar su aplicación Angular 9 en Firebase Hosting

En este paso, veremos cómo compilar e implementar nuestra aplicación de ejemplo en el alojamiento de Firebase usando el comando ng deploy disponible en Angular 8.3+.

Solo veremos cómo implementar la aplicación frontend sin el servidor JSON falso.

Angular CLI 8.3+ introdujo un nuevo ng deploycomando que hace que sea más fácil que antes implementar su aplicación Angular utilizando el constructor de implementación CLI asociado con su proyecto. Hay muchos constructores de terceros que implementan capacidades de implementación para diferentes plataformas. Puede agregar cualquiera de ellos a su proyecto ejecutando el ng addcomando.

Después de agregar un paquete de implementación, se actualizará automáticamente la configuración de su espacio de trabajo (es decir, el angular.jsonarchivo) con una sección de implementación para el proyecto seleccionado. Luego puede usar el ng deploycomando para implementar ese proyecto.

Veamos ahora eso con un ejemplo al implementar nuestro proyecto en el alojamiento de Firebase.

Regrese a su interfaz de línea de comandos, asegúrese de estar dentro de la carpeta raíz de su proyecto Angular y ejecute el siguiente comando:

$ ng add @angular/fire

Esto agregará la capacidad de implementación de Firebase a su proyecto.

El comando también actualizará el package.jsonde nuestro proyecto agregando esta sección:

        "deploy": {
          "builder": "@angular/fire:deploy",
          "options": {}
        }

La CLI le pedirá que pegue el código de autorización aquí: y abrirá su navegador web predeterminado y le pedirá que otorgue permisos a Firebase CLI para administrar su cuenta de Firebase:

Después de iniciar sesión con la cuenta de Google asociada con su cuenta de Firebase, se le dará el código de autorización:

A continuación, se le pedirá: Seleccione un proyecto: (Utilice las teclas de flecha o escriba para buscar) . Deberías haber creado un proyecto de Firebase antes.

La CLI creará las firebase.jsony los .firebasercarchivos y actualizar el angular.jsonarchivo en consecuencia.

Luego, implemente su aplicación en Firebase con el siguiente comando:

$ ng deploy

El comando producirá una compilación optimizada de su aplicación (equivalente al ng deploy --prodcomando), cargará los activos de producción en el alojamiento de Firebase.

Conclusión

A lo largo de este tutorial de Angular 9, hemos creado un ejemplo completo de aplicación Angular funcional utilizando la última versión.

Como recapitulación, hemos visto particularmente por ejemplo cómo configurar HttpClienty enviar solicitudes HTTP GET con parámetros usando el HttpClient.get()método, cómo manejar errores HTTP usando RxJS throwError()catchError()operadores, darse de baja de RxJS Observables para las solicitudes HTTP canceladas usando el takeUntil()operador y reintente las solicitudes fallidas con el retry()operador y, finalmente, cómo implementar nuestra aplicación en el alojamiento de Firebase utilizando la última ng deployfunción disponible de Angular 8.3+.


Publicar un comentario

0 Comentarios