En esta sección, aprenderemos cómo realizar solicitudes HTTP en Angular utilizando el módulo HttpClient. Este módulo nos permite comunicarnos con servidores remotos a través de HTTP, lo cual es esencial para la mayoría de las aplicaciones web modernas.

Contenido

Configuración del HttpClientModule

Antes de poder realizar solicitudes HTTP, necesitamos importar y configurar el HttpClientModule en nuestra aplicación Angular.

  1. Abre el archivo app.module.ts.
  2. Importa HttpClientModule desde @angular/common/http.
  3. Añade HttpClientModule a la lista de imports en el decorador @NgModule.
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';

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

Realizando una Solicitud GET

Las solicitudes GET se utilizan para recuperar datos de un servidor. Vamos a crear un servicio que realice una solicitud GET para obtener datos de una API.

  1. Crea un nuevo servicio utilizando Angular CLI:

    ng generate service data
    
  2. Abre el archivo data.service.ts y añade el siguiente código:

// data.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

  private apiUrl = 'https://jsonplaceholder.typicode.com/posts';

  constructor(private http: HttpClient) { }

  getPosts(): Observable<any> {
    return this.http.get<any>(this.apiUrl);
  }
}
  1. Ahora, inyecta este servicio en un componente y utiliza el método getPosts para obtener los datos.
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { DataService } from './data.service';

@Component({
  selector: 'app-root',
  template: `
    <div *ngIf="posts">
      <h1>Posts</h1>
      <ul>
        <li *ngFor="let post of posts">{{ post.title }}</li>
      </ul>
    </div>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  posts: any;

  constructor(private dataService: DataService) {}

  ngOnInit() {
    this.dataService.getPosts().subscribe(data => {
      this.posts = data;
    });
  }
}

Realizando una Solicitud POST

Las solicitudes POST se utilizan para enviar datos a un servidor. Vamos a modificar nuestro servicio para incluir un método que realice una solicitud POST.

  1. Añade el siguiente método al archivo data.service.ts:
// data.service.ts
import { HttpHeaders } from '@angular/common/http';

// ...

addPost(post: any): Observable<any> {
  const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
  return this.http.post<any>(this.apiUrl, post, { headers });
}
  1. Modifica el componente para incluir un formulario que permita añadir un nuevo post.
// app.component.ts
import { FormBuilder, FormGroup } from '@angular/forms';

// ...

export class AppComponent implements OnInit {
  posts: any;
  postForm: FormGroup;

  constructor(private dataService: DataService, private fb: FormBuilder) {
    this.postForm = this.fb.group({
      title: [''],
      body: ['']
    });
  }

  ngOnInit() {
    this.dataService.getPosts().subscribe(data => {
      this.posts = data;
    });
  }

  onSubmit() {
    this.dataService.addPost(this.postForm.value).subscribe(newPost => {
      this.posts.push(newPost);
    });
  }
}
  1. Actualiza la plantilla para incluir el formulario.
<!-- app.component.html -->
<div *ngIf="posts">
  <h1>Posts</h1>
  <ul>
    <li *ngFor="let post of posts">{{ post.title }}</li>
  </ul>
</div>

<form [formGroup]="postForm" (ngSubmit)="onSubmit()">
  <label for="title">Title:</label>
  <input id="title" formControlName="title">
  
  <label for="body">Body:</label>
  <textarea id="body" formControlName="body"></textarea>
  
  <button type="submit">Add Post</button>
</form>

Manejo de Errores

Es importante manejar los errores que puedan ocurrir durante las solicitudes HTTP. Podemos utilizar el operador catchError de RxJS para esto.

  1. Modifica el método getPosts en data.service.ts para manejar errores:
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

// ...

getPosts(): Observable<any> {
  return this.http.get<any>(this.apiUrl).pipe(
    catchError(this.handleError)
  );
}

private handleError(error: any) {
  console.error('An error occurred:', error);
  return throwError('Something bad happened; please try again later.');
}

Ejercicio Práctico

Ejercicio

  1. Crea un nuevo servicio llamado user.service.ts que realice solicitudes GET y POST a la API https://jsonplaceholder.typicode.com/users.
  2. En el componente principal, muestra una lista de usuarios y un formulario para añadir un nuevo usuario.

Solución

  1. Crea el servicio:

    ng generate service user
    
  2. Implementa el servicio:

// user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

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

  private apiUrl = 'https://jsonplaceholder.typicode.com/users';

  constructor(private http: HttpClient) { }

  getUsers(): Observable<any> {
    return this.http.get<any>(this.apiUrl).pipe(
      catchError(this.handleError)
    );
  }

  addUser(user: any): Observable<any> {
    const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
    return this.http.post<any>(this.apiUrl, user, { headers }).pipe(
      catchError(this.handleError)
    );
  }

  private handleError(error: any) {
    console.error('An error occurred:', error);
    return throwError('Something bad happened; please try again later.');
  }
}
  1. Modifica el componente principal:
// app.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { UserService } from './user.service';

@Component({
  selector: 'app-root',
  template: `
    <div *ngIf="users">
      <h1>Users</h1>
      <ul>
        <li *ngFor="let user of users">{{ user.name }}</li>
      </ul>
    </div>

    <form [formGroup]="userForm" (ngSubmit)="onSubmit()">
      <label for="name">Name:</label>
      <input id="name" formControlName="name">
      
      <label for="email">Email:</label>
      <input id="email" formControlName="email">
      
      <button type="submit">Add User</button>
    </form>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  users: any;
  userForm: FormGroup;

  constructor(private userService: UserService, private fb: FormBuilder) {
    this.userForm = this.fb.group({
      name: [''],
      email: ['']
    });
  }

  ngOnInit() {
    this.userService.getUsers().subscribe(data => {
      this.users = data;
    });
  }

  onSubmit() {
    this.userService.addUser(this.userForm.value).subscribe(newUser => {
      this.users.push(newUser);
    });
  }
}

Conclusión

En esta sección, hemos aprendido cómo realizar solicitudes HTTP GET y POST utilizando el módulo HttpClient de Angular. También hemos visto cómo manejar errores en nuestras solicitudes HTTP. Estos conceptos son fundamentales para interactuar con APIs y servidores en aplicaciones web modernas.

En la próxima sección, exploraremos cómo manejar las respuestas HTTP y cómo trabajar con Observables para gestionar flujos de datos asíncronos en Angular.

Curso de Angular 2+

Módulo 1: Introducción a Angular

Módulo 2: Conceptos Básicos de TypeScript

Módulo 3: Componentes y Plantillas

Módulo 4: Directivas y Pipes

Módulo 5: Servicios e Inyección de Dependencias

Módulo 6: Enrutamiento y Navegación

Módulo 7: Formularios en Angular

Módulo 8: Cliente HTTP y Observables

Módulo 9: Gestión de Estado

Módulo 10: Pruebas en Angular

Módulo 11: Temas Avanzados

Módulo 12: Despliegue y Mejores Prácticas

© Copyright 2024. Todos los derechos reservados