En este módulo, aprenderemos cómo realizar solicitudes HTTP y trabajar con APIs en una aplicación Ionic. Este es un aspecto crucial del desarrollo de aplicaciones modernas, ya que la mayoría de las aplicaciones necesitan interactuar con servidores para obtener o enviar datos.

Contenidos

Introducción a las Solicitudes HTTP

Las solicitudes HTTP son la forma en que las aplicaciones web y móviles se comunican con los servidores. Ionic, al estar basado en Angular, utiliza el módulo HttpClient de Angular para realizar estas solicitudes de manera eficiente y sencilla.

Tipos de Solicitudes HTTP

  • GET: Recupera datos del servidor.
  • POST: Envía datos al servidor.
  • PUT: Actualiza datos en el servidor.
  • DELETE: Elimina datos del servidor.

Configuración del Módulo HttpClient

Antes de realizar cualquier solicitud HTTP, necesitamos configurar el módulo HttpClient en nuestra aplicación Ionic.

  1. Instalación: Asegúrate de que el módulo HttpClient esté instalado. Generalmente, viene preinstalado con Angular, pero puedes verificarlo con el siguiente comando:

    npm install @angular/common@latest
    
  2. Importación: Importa el módulo HttpClientModule en tu módulo principal (app.module.ts):

    import { HttpClientModule } from '@angular/common/http';
    
    @NgModule({
      declarations: [AppComponent],
      imports: [
        BrowserModule,
        IonicModule.forRoot(),
        AppRoutingModule,
        HttpClientModule // Importa HttpClientModule aquí
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule {}
    

Realizando Solicitudes GET

Las solicitudes GET se utilizan para recuperar datos del servidor. A continuación, se muestra un ejemplo de cómo realizar una solicitud GET en Ionic.

  1. Servicio: Crea un servicio para manejar las solicitudes HTTP. En este ejemplo, crearemos un servicio llamado DataService.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataService {
      private apiUrl = 'https://api.example.com/data';
    
      constructor(private http: HttpClient) {}
    
      getData(): Observable<any> {
        return this.http.get<any>(this.apiUrl);
      }
    }
    
  2. Componente: Utiliza el servicio en un componente para obtener y mostrar los datos.

    import { Component, OnInit } from '@angular/core';
    import { DataService } from '../services/data.service';
    
    @Component({
      selector: 'app-home',
      templateUrl: 'home.page.html',
      styleUrls: ['home.page.scss'],
    })
    export class HomePage implements OnInit {
      data: any;
    
      constructor(private dataService: DataService) {}
    
      ngOnInit() {
        this.dataService.getData().subscribe(response => {
          this.data = response;
        });
      }
    }
    
  3. Template: Muestra los datos en el template del componente.

    <ion-header>
      <ion-toolbar>
        <ion-title>
          Home
        </ion-title>
      </ion-toolbar>
    </ion-header>
    
    <ion-content>
      <ion-list>
        <ion-item *ngFor="let item of data">
          {{ item.name }}
        </ion-item>
      </ion-list>
    </ion-content>
    

Realizando Solicitudes POST

Las solicitudes POST se utilizan para enviar datos al servidor. A continuación, se muestra un ejemplo de cómo realizar una solicitud POST en Ionic.

  1. Servicio: Añade un método para realizar una solicitud POST en el servicio DataService.

    import { Injectable } from '@angular/core';
    import { HttpClient } from '@angular/common/http';
    import { Observable } from 'rxjs';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataService {
      private apiUrl = 'https://api.example.com/data';
    
      constructor(private http: HttpClient) {}
    
      getData(): Observable<any> {
        return this.http.get<any>(this.apiUrl);
      }
    
      postData(data: any): Observable<any> {
        return this.http.post<any>(this.apiUrl, data);
      }
    }
    
  2. Componente: Utiliza el servicio en un componente para enviar datos.

    import { Component } from '@angular/core';
    import { DataService } from '../services/data.service';
    
    @Component({
      selector: 'app-home',
      templateUrl: 'home.page.html',
      styleUrls: ['home.page.scss'],
    })
    export class HomePage {
      newData = { name: 'New Item' };
    
      constructor(private dataService: DataService) {}
    
      addData() {
        this.dataService.postData(this.newData).subscribe(response => {
          console.log('Data added:', response);
        });
      }
    }
    
  3. Template: Añade un botón para enviar los datos.

    <ion-header>
      <ion-toolbar>
        <ion-title>
          Home
        </ion-title>
      </ion-toolbar>
    </ion-header>
    
    <ion-content>
      <ion-button (click)="addData()">Add Data</ion-button>
    </ion-content>
    

Manejo de Errores en Solicitudes HTTP

Es importante manejar los errores que pueden ocurrir durante las solicitudes HTTP. Angular proporciona operadores de RxJS como catchError para manejar estos errores.

  1. Servicio: Modifica el servicio para manejar errores.

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpErrorResponse } from '@angular/common/http';
    import { Observable, throwError } from 'rxjs';
    import { catchError } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root'
    })
    export class DataService {
      private apiUrl = 'https://api.example.com/data';
    
      constructor(private http: HttpClient) {}
    
      getData(): Observable<any> {
        return this.http.get<any>(this.apiUrl).pipe(
          catchError(this.handleError)
        );
      }
    
      postData(data: any): Observable<any> {
        return this.http.post<any>(this.apiUrl, data).pipe(
          catchError(this.handleError)
        );
      }
    
      private 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}`;
        }
        return throwError(errorMessage);
      }
    }
    
  2. Componente: Maneja los errores en el componente.

    import { Component, OnInit } from '@angular/core';
    import { DataService } from '../services/data.service';
    
    @Component({
      selector: 'app-home',
      templateUrl: 'home.page.html',
      styleUrls: ['home.page.scss'],
    })
    export class HomePage implements OnInit {
      data: any;
      error: string;
    
      constructor(private dataService: DataService) {}
    
      ngOnInit() {
        this.dataService.getData().subscribe(
          response => {
            this.data = response;
          },
          error => {
            this.error = error;
          }
        );
      }
    
      addData() {
        this.dataService.postData({ name: 'New Item' }).subscribe(
          response => {
            console.log('Data added:', response);
          },
          error => {
            this.error = error;
          }
        );
      }
    }
    
  3. Template: Muestra los errores en el template.

    <ion-header>
      <ion-toolbar>
        <ion-title>
          Home
        </ion-title>
      </ion-toolbar>
    </ion-header>
    
    <ion-content>
      <ion-list *ngIf="data">
        <ion-item *ngFor="let item of data">
          {{ item.name }}
        </ion-item>
      </ion-list>
      <ion-button (click)="addData()">Add Data</ion-button>
      <ion-text color="danger" *ngIf="error">{{ error }}</ion-text>
    </ion-content>
    

Ejercicio Práctico

Ejercicio

  1. Crea un servicio llamado UserService que realice solicitudes GET y POST a una API ficticia https://jsonplaceholder.typicode.com/users.
  2. En un componente, utiliza este servicio para obtener una lista de usuarios y mostrarla en una lista.
  3. Añade un formulario para agregar un nuevo usuario y envíalo a la API utilizando una solicitud POST.

Solución

  1. Servicio UserService:

    import { Injectable } from '@angular/core';
    import { HttpClient, HttpErrorResponse } from '@angular/common/http';
    import { Observable, throwError } from 'rxjs';
    import { catchError } from 'rxjs/operators';
    
    @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> {
        return this.http.post<any>(this.apiUrl, user).pipe(
          catchError(this.handleError)
        );
      }
    
      private handleError(error: HttpErrorResponse) {
        let errorMessage = 'Unknown error!';
        if (error.error instanceof ErrorEvent) {
          errorMessage = `Error: ${error.error.message}`;
        } else {
          errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
        }
        return throwError(errorMessage);
      }
    }
    
  2. Componente:

    import { Component, OnInit } from '@angular/core';
    import { UserService } from '../services/user.service';
    
    @Component({
      selector: 'app-users',
      templateUrl: './users.page.html',
      styleUrls: ['./users.page.scss'],
    })
    export class UsersPage implements OnInit {
      users: any;
      error: string;
      newUser = { name: '', email: '' };
    
      constructor(private userService: UserService) {}
    
      ngOnInit() {
        this.userService.getUsers().subscribe(
          response => {
            this.users = response;
          },
          error => {
            this.error = error;
          }
        );
      }
    
      addUser() {
        this.userService.addUser(this.newUser).subscribe(
          response => {
            this.users.push(response);
          },
          error => {
            this.error = error;
          }
        );
      }
    }
    
  3. Template:

    <ion-header>
      <ion-toolbar>
        <ion-title>
          Users
        </ion-title>
      </ion-toolbar>
    </ion-header>
    
    <ion-content>
      <ion-list *ngIf="users">
        <ion-item *ngFor="let user of users">
          {{ user.name }} - {{ user.email }}
        </ion-item>
      </ion-list>
      <ion-item>
        <ion-label position="floating">Name</ion-label>
        <ion-input [(ngModel)]="newUser.name"></ion-input>
      </ion-item>
      <ion-item>
        <ion-label position="floating">Email</ion-label>
        <ion-input [(ngModel)]="newUser.email"></ion-input>
      </ion-item>
      <ion-button (click)="addUser()">Add User</ion-button>
      <ion-text color="danger" *ngIf="error">{{ error }}</ion-text>
    </ion-content>
    

Conclusión

En esta sección, hemos aprendido cómo realizar solicitudes HTTP y trabajar con APIs en una aplicación Ionic. Hemos cubierto cómo configurar el módulo HttpClient, realizar solicitudes GET y POST, y manejar errores en las solicitudes HTTP. Además, hemos puesto en práctica estos conceptos con un ejercicio práctico.

En el próximo módulo, exploraremos cómo almacenar datos localmente en una aplicación Ionic.

© Copyright 2024. Todos los derechos reservados