Tutorial de Ionic – Peticiones http – API REST

En el siguiente enlace tienes el 铆ndice para acceder al resto de entradas de este tutorial:

 

隆隆Atenci贸n!! este tutorial se basa en ionic 3 y est谩 desactualizado por lo que es posible que los ejemplos no funcionen en la 煤ltima versi贸n de ionic, haz click aqu铆 para acceder a un tutorial mas actual de Ionic.

 

Hola a todos, 聽hoy vamos a ver como podemos comunicar una aplicaci贸n desarrollada con ionic con una API REST,聽para ello vamos a aprender como realizar peticiones a un servidor remoto a trav茅s de http.

En esta peque帽a prueba vamos a ver como podemos acceder a una API REST para obtener desde un servidor remoto un listado de usuarios. Para este peque帽o ejemplo vamos a utilizar聽RANDOM USER GENERATOR que como se indica en su web es una API libre de c贸digo abierto para generar datos de usuario aleatorios para realizar pruebas. Como Lorem Ipsum, pero con personas.

Lo que vamos a hacer es simplemente realizar una llamada a esta API donde recibiremos como respuesta un listado de usuarios que mostraremos en nuestra vista.

Antes de nada vamos a crear una nueva aplicaci贸n de prueba:

ionic start pruebahttp1 blank

Ahora vamos a crear un provider donde gestionaremos la comunicaci贸n con el servidor remoto:

ionic g provider http

Se habr谩 creado una carpeta providers (si no exist铆a) y dentro una carpeta con el nombre del provider que acabamos de crear (http) y dentro un archivo .ts con el mismo nombre.

Por defecto contendr谩 el siguiente c贸digo:

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

/*
聽聽Generated class for the HttpProvider provider.

聽聽See https://angular.io/guide/dependency-injection for more info on providers
聽聽and Angular DI.
*/
@Injectable()
export class HttpProvider {

  constructor(public http: HttpClient) {
    console.log('Hello HttpProvider Provider');
  }

}

Vemos que al crear un provider ya se importa el m贸dulo HttpClient.

Para poder utilizar HttpClient tenemos que importar y declarar HttpClientModule en el archivo app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { ErrorHandler, NgModule } from '@angular/core';
import { IonicApp, IonicErrorHandler, IonicModule } from 'ionic-angular';
import { SplashScreen } from '@ionic-native/splash-screen';
import { StatusBar } from '@ionic-native/status-bar';

import { MyApp } from './app.component';
import { HomePage } from '../pages/home/home';
import { HttpProvider } from '../providers/http/http';
import { HttpClientModule } from '@angular/common/http';



@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    HttpClientModule
    
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage
  ],
  providers: [
    StatusBar,
    SplashScreen,
    {provide: ErrorHandler, useClass: IonicErrorHandler},
    HttpProvider
  ]
})
export class AppModule {}

http.get

Ahora vamos a a帽adir un m茅todo que llamaremos loadUsers a nuestro provider para obtener la lista de usuarios desde el servidor, por lo tanto editamos el archivo http.ts y a帽adimos el siguiente c贸digo:
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';

/*
聽聽Generated class for the HttpProvider provider.

聽聽See https://angular.io/guide/dependency-injection for more info on providers
聽聽and Angular DI.
*/
@Injectable()
export class HttpProvider {

  path : string = 'https://randomuser.me/api/?results=25';
  
  constructor(public http: HttpClient) {
    console.log('Hello HttpProvider Provider');
  }

  loadUsers(){
    return this.http
    .get(this.path)
  }
}
http.get devuelve el resultado de la solicitud en la forma de un observable.
El listado de usuarios tendr谩 un formato similar a este:
{
聽聽"results": [
聽聽聽聽{
聽聽聽聽聽聽"gender": "male",
聽聽聽聽聽聽"name": {
聽聽聽聽聽聽聽聽"title": "mr",
聽聽聽聽聽聽聽聽"first": "romain",
聽聽聽聽聽聽聽聽"last": "hoogmoed"
聽聽聽聽聽聽},
      "location": {
聽聽聽聽聽聽聽聽"street": "1861 jan pieterszoon coenstraat",
聽聽聽聽聽聽聽聽"city": "maasdriel",
聽聽聽聽聽聽聽聽"state": "zeeland",
聽聽聽聽聽聽聽聽"postcode": 69217
聽聽聽聽聽聽},
      "email": "romain.hoogmoed@example.com",
      "login": {
聽聽聽聽聽聽聽聽"username": "lazyduck408",
聽聽聽聽聽聽聽聽"password": "jokers",
聽聽聽聽聽聽聽聽"salt": "UGtRFz4N",
聽聽聽聽聽聽聽聽"md5": "6d83a8c084731ee73eb5f9398b923183",
聽聽聽聽聽聽聽聽"sha1": "cb21097d8c430f2716538e365447910d90476f6e",
聽聽聽聽聽聽聽聽"sha256": "5a9b09c86195b8d8b01ee219d7d9794e2abb6641a2351850c49c309f1fc204a0"
聽聽聽聽聽聽},
      "dob": "1983-07-14 07:29:45",
      "registered": "2010-09-24 02:10:42",
      "phone": "(656)-976-4980",
      "cell": "(065)-247-9303",
      "id": {
聽聽聽聽聽聽聽聽"name": "BSN",
聽聽聽聽聽聽聽聽"value": "04242023"
聽聽聽聽聽聽},
      "picture": {
聽聽聽聽聽聽聽聽"large": "https://randomuser.me/api/portraits/men/83.jpg",
聽聽聽聽聽聽聽聽"medium": "https://randomuser.me/api/portraits/med/men/83.jpg",
聽聽聽聽聽聽聽聽"thumbnail": "https://randomuser.me/api/portraits/thumb/men/83.jpg"
聽聽聽聽聽聽},
      "nat": "NL"
    }
  ],
  "info": {
聽聽聽聽"seed": "2da87e9305069f1d",
聽聽聽聽"results": 1,
聽聽聽聽"page": 1,
聽聽聽聽"version": "1.1"
聽聽}
}
Ahora vamos a crear la vista en home.html para mostrar un bot贸n que llamar谩 a la funci贸n
cargarUsuarios,y un listado de items con los usuarios que crearemos recorriendo con *ngFor el array usuarios que posteriormente vamos a crear en el controlador:
<ion-header>
  <ion-navbar>
    <ion-title>
      Usuarios
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content>
  <ion-list>
    <ion-item *ngFor="let usuario of usuarios">
      <ion-avatar item-start>
        <img [src]="usuario.picture.medium">
      </ion-avatar>
      <h2>{{ usuario.name.first }}</h2>
      <p>{{ usuario.email }}</p>
    </ion-item>
  </ion-list>
  <button ion-button full (click) = "cargarUsuarios()">Cargar Usuarios</button>
</ion-content>
Ahora vamos a modificar home.ts para obtener los datos desde el provider y mostrarlos en la vista.
Editamos home.ts e importamos el provider httpProvider que acabamos de crear:
import { HttpProvider } from '../../providers/http/http';
Para poder utilizarlo debemos inyectarlo en el constructor:
constructor(public navCtrl: NavController, public http: HttpProvider) {

  }
Justo antes del constructor vamos a definir una variable miembro donde guardaremos el array de usuarios que recibamos desde el servidor:
usuarios : any[];

Promesas y Observables

Ahora vamos a crear un m茅todo que que a su vez llamar谩 al m茅todo loadUsers de nuestro provider para recibir los datos de los usuarios:
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { HttpProvider } from '../../providers/http/http';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  usuarios : any[];

  constructor(public navCtrl: NavController, public http: HttpProvider) {

  }

  cargarUsuarios(){
    this.http.loadUsers().subscribe(
      (res) => { 
        this.usuarios = res['results'];
      },
      (error) =>{
        console.error(error);
      }
    )
  }


}

Como podemos observar llamamos al m茅todo loadUsers聽que hemos definido en el provider, pero no utilizamos then sino subscribe, esto es porque http no devuelve una promesa si no que devuelve un observable. Un observable se queda a la espera de recibir datos y nosotros nos “subscribimos” recibiendo estos datos en cuanto est茅n disponibles.
Esta cualidad se puede utilizar para suscribirnos a la url y observar si ha habido cambios, como por ejemplo si es un sitio de noticias donde se est谩n continuamente renovando.

La diferencia entre promesas y observables a groso modo es que la promesa devuelve los datos una 煤nica vez cuando estos son recibidos mientras que un observable se queda “vigilando” si se han producido cambios y se ejecuta cada vez que un cambio se produce, aunque hasta que no te suscribes a un observable 茅ste no se ejecutar谩.

Si solo necesitamos recibir los datos una 煤nica vez sin necesidad de observar si se han producido cambios podemos utilizar promesas. Una promesa se ejecuta una vez que se haya resuelto la llamada y recibimos los datos en la funci贸n .then(res=>{… }).

El c贸digo del provider en el archivo http.ts utilizando una promesa quedar铆a de la siguiente manera:

import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/toPromise';

/*
聽聽Generated class for the HttpProvider provider.

聽聽See https://angular.io/guide/dependency-injection for more info on providers
聽聽and Angular DI.
*/
@Injectable()
export class HttpProvider {

  path : string = 'https://randomuser.me/api/?results=25';
  
  constructor(public http: HttpClient) {
    console.log('Hello HttpProvider Provider');
  }

  loadUsers(){
    return this.http
    .get(this.path)
    .toPromise();

  }  
}

Debemos importar el operador toPromise聽para convertir el observable en promesa 聽con import ‘rxjs/add/operator/toPromise’;聽 y simplemente a帽adir toPromise()聽despu茅s del get.

Ahora en home.ts聽solo tenemos que sustituir subscribe por then:

cargarUsuarios(){
  this.http.loadUsers().then(
    (res) => { 
      this.usuarios = res['results'];
    },
    (error) =>{
      console.error(error);
    }
  )
}

Si ejecut谩is la aplicaci贸n con ionic serve -l y puls谩is en el bot贸n Cargar Usuarios podr茅is ver algo como esto:

Listado de usuarios
Listado de usuarios

Pod茅is observar como cada vez que puls茅is el bot贸n la lista de usuarios cambia ya que Random User Generator como su propio nombre indica devuelve una lista aleatoria de usuarios.

http.post

RANDOM USER GENERATOR聽 nos ha servido para aprender ha hacer una petici贸n get a una API REST para recibir datos, en este caso una lista de usuarios.

Si quer茅is conectaros con un servicio que teng谩is corriendo en un servidor remoto y necesit谩is pasarle datos desde la aplicaci贸n para que se guarden en el servidor tenemos que usar http.post.

Vamos a imaginar que tenemos corriendo un servicio en PHP cuya url sea www.miservicio.com/adduser/聽que est谩 programado para recibir v铆a post un nuevo usuario para guardarlo en la base de datos del servidor.

Tendremos que crear 聽una funci贸n similar a esta:

postDatos(){
  let datos = { nombre:'Edu',email:'edu.revilla.vaquero@gmail.com'}
  
  let options = {
聽聽聽聽headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  };
 var url = 'www.miservicio.com/adduser/';
 return new Promise(resolve => {
  this.http.post(url,JSON.stringify(datos),options)
     .subscribe(data => {
       resolve(data);
      });
 });
}

En la variable datos 聽tenemos un objeto con los datos del usuario que queremos enviar al servidor, en este caso nombre y email.

Despu茅s definimos la variable options donde a su vez definimos las cabeceras en la variable headers, dependiendo de la configuraci贸n del servidor podr铆a necesitar par谩metros diferentes en la cabecera.

Como vemos http.post es bastante parecido a http.get, solo que como segundo par谩metro le pasamos la variable que contiene los datos que queremos enviar convertida a formato JSON con聽JSON.stringify(datos), como tercer par谩metro le pasamos options.

En聽data聽recibiremos la respuesta que nos de el servidor.

Vamos a ver un ejemplo de como obtendr铆amos los datos enviados desde nuestra aplicaci贸n con un servicio desarrollado en PHP en el servidor:

<?php
$postdata = file_get_contents("php://input");
if (isset($postdata)) {
$request = json_decode($postdata);
echo $request->nombre;
echo $request->email;
}
?>

Evidentemente en otros lenguajes de programaci贸n del lado del servidor el c贸digo para recibir los datos ser铆a diferente, pero se escapa del prop贸sito de este tutorial el abordar como ser铆a en cada leguaje. Si alguno hace la prueba en otro lenguaje y quiere compartirlo en los comentarios para ayudar a los dem谩s ser谩 bien recibido :-).

Eso es todo por hoy.

Si necesitas desarrollar una aplicaci贸n m贸vil no dudes en solicitarme un presupuesto sin compromiso:

Un saludo, y si a煤n no lo has hecho no olvides suscribirte a mi blog para no perderte los pr贸ximos posts 聽:-),

Tambi茅n puedes seguirme en Twitter en 鈥嶡revigames y no olvides que me ayudas mucho聽si compartes este post en las redes sociales.

19 comentarios en “Tutorial de Ionic – Peticiones http – API REST

  1. Hola Edu, genial el post, aclara muchisimas cosas y la verdad que explica el tema de los observables y promesas de forma que se entienda a la perfecci贸n… mis felicitaciones.

    Quiero comentarte que tengo un problemilla, creo que lo tengo todo hecho como tu indicas en el post pero cuando lanzo la app en servidor y tambien en dispositivo me da un error cuando pulso el bot贸n para que me descargue los datos.

    este es el error:
    Failed to navigate: No provider for HttpProvider!

    驴tienes idea de que puedo estar haciendo mal?

    1. // Importar Necesariamente estos dos///
      import { HttpClientModule } from ‘@angular/common/http’;
      import { HttpModule } from ‘@angular/http’;

      Importa esos dos modulos

  2. Hola edu amo este blog, es genial todos tus tutos, pero tengo un problema, cuando intento testear en mi android me tira un error con la funcion json de loadusers(), mira:

    [00:54:51] typescript: C:/Users/Jaime/Desktop/htdocs/Trabajo/hola-mundo/src/providers/http.ts, line: 23
    Property ‘json’ does not exist on type ‘Object’.

    L22: .get(this.path)
    L23: .map(res => res.json(),
    L24: err => {

    [00:54:51] ionic-app-script task: “build”
    [00:54:51] Error: Failed to transpile program
    Error: Failed to transpile program
    at new BuildError (C:\Users\Jaime\Desktop

    Muchas gracias igual, y segui asi es genial!!

    1. Hola Ezequiel:
      A partir de la versi贸n 4.3 de Angular han incorporado HttpClient en lugar de Http. Ionic ahora utiliza HttpClient por lo que Http ha quedado deprecado.
      Acabo de actualizar el post para utilizar HttpClient en lugar de Http.

      Muchas gracias por comentar

      Un saludo

  3. Hola Ezequiel,

    Compr茅 tu libro en Amazon apenas una semana despu茅s de que lo atualizaras a la versi贸n 3 de Ionic (fue casualidad). Cuando llegu茅 al cap铆tulo del API Rest no me funcionaba nada y despu茅s de pelearme record茅 que tinenes un blog (lo encontr茅 poniendo tu nombre poco despu茅s de comprarlo). Con la actualizaci贸n que has puesto aqu铆 me funciona perfectamente. Sin embargo, estoy intentando hacer la parte no resuelta del http.post y obtengo un error de importaci贸n con el m茅todo “post”.

    Aprovecho el mensaje para pedirte por favor bibliograf铆a tuya o de otros autores, o curso online que me puedan servir para entender mejor este framework. 驴Merece la pena que me mire AngularJS si s贸lo me interesa Ionic por las app m贸viles y no “apps web”?

    Felicitaciones por el libro. Sirve realmente para comenzar desde cero y es de lo poco que hay en castellano.

    1. Hola Juanma,

      Antes de nada gracias por comprar el libro.
      Supongo que la consulta es para mi y no para Ezequiel :),

      La verdad es que es complicado mantener el libro actualizado ya que con cada nueva versi贸n de ionic salen funcionalidades nuevas y algunas cosas quedan obsoletas, intento no obstante tener el contenido lo m谩s actualizado posible.

      Por un lado para ver si puedo ayudarte 驴podr铆as indicar que error te sale exactamente al utilizar el m茅todo post?

      Por otro lado libros en espa帽ol sobre Ionic apenas hay, por eso me decid铆 a escribir uno, sin embargo cursos online si he visto varios, si buscas en google no te costar谩 encontrar alguno.
      Si te defiendes en ingl茅s si que puedes encontrar algo m谩s de material, tambien tienes la propia documentaci贸n oficial de ionic.

      En cuanto a aprender AngularJS, te dir茅 que en realidad se denomina as铆 a la versi贸n 1, a partir de la versi贸n 2 se denomina simplemente Angular, esto es as铆 porque son totalmente diferentes y no compatibles entre si.
      Como Ionic se basa en Angular, aunque solo te interese desarrollar apps m贸viles si creo que es muy recomendable que trates de aprender Angular, aunque en mi libro explico conceptos b谩sicos de Angular para defenderte con Ionic y empezar a desarrollar tus aplicaciones cuanto m谩s sepas de Angular m谩s herramientas tendr谩s para construir tus aplicaciones.
      Si buscas en google no te costar谩 encontrar cursos online y libros para aprender.

      Un saludo

      1. Ostras s铆, entre el Ezequiel del otro comentario y mi compa帽ero de trabajo (tambi茅n se llama as铆) me he liado. Sobre el error del m茅todo “http.post” ya est谩 resuelto, era culpa m铆a.
        En un par de semanas comenzar茅 por el cap铆tulo de Firebase.

        Gracias por tu pronta respuesta.
        Un saludo.

  4. Hola Eduardo,
    estoy intentando ejecutar el comando ionic g provider http pero me esta saliendo este error:
    Error: Cannot find module ‘C:\Users\MORENO ARAQUE\Desktop\pruebahttp1\node_modules\@ionic\app-scripts’
    Que paso estoy omitiendo o que estoy haciendo mal? Gracias
    Esto en VisualstudioCode Windows 10

  5. no me sale el post hice como el tuyo cambie mi url por una local pero la parte de header debe ir exactamente igual al de tu blog o debo cambiar??

  6. Hola eduardo,

    Logr茅 hacer el ejemplo de este post satisfactoriamente, muy bueno por cierto.

    Quiero hacer la coneccion con un webservice creado con node.js pero en la consola me arroja el siguiente error:
    from origin ‘http://localhost:8100’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

    ya realize los pasos de tu post: ‘Como mejorar el rendimiento de ionic en iOS y soluci贸n al problema de las peticiones http CORS’

    pero sigo obteniendo el mismo error

    de antemano gracias

  7. Muchas gracias, excelente el articulo, probe el http.get y corre sin problemas, pero probe el http.post y me sale el siguiente error:

    ERROR Error: Uncaught (in promise): TypeError: _this.http.post is not a function
    TypeError: _this.http.post is not a function

Deja una respuesta

Tu direcci贸n de correo electr贸nico no ser谩 publicada. Los campos obligatorios est谩n marcados con *

Este sitio usa Akismet para reducir el spam. Aprende c贸mo se procesan los datos de tus comentarios.