APIs e Microsserviços

9 nov, 2017

Ionic 3: Consumindo API da Marvel

Publicidade

Neste artigo, veja como criar um app mobile com Ionic na versão 3. Para você ter um overview, vou aproveitar a API disponibilizada gratuitamente pela Marvel para mostrar como consumir dados externos de uma API. Não vou abordar a instalação do Ionic. Caso você ainda não tenha ele instalado, basta seguir os passos demonstrados no site oficial.

O primeiro passo é escolher um diretório para a aplicação. Em seguida, execute no terminal o comando demonstrado abaixo.

ionic start apiApp blank

O comando ionic start irá criar um novo projeto chamado apiApp com o template blank. Para o próximo passo, você precisará de um editor de textos. Neste artigo, iremos utilizar o Visual Studio Code. Abaixo, veja a estrutura do projeto que acabamos de criar aberta no VS Code.

Estrutura projeto Ionic 3

Depois de criar uma estrutura básica para o app, você precisa criar um provider para acessar dados externos. Para isso, execute o comando abaixo no terminal. Ele irá criar um novo @Injectable dentro da solução, chamado HeroService, na seguinte estrutura: app/providers/hero-service/hero-service.ts

ionic g provider HeroService

Agora implemente o código necessário para que o provider faça uma requisição GET na API da Marvel.

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { Md5 } from 'ts-md5/dist/md5';

/*
  Generated class for the HeroService provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class HeroService {
  data: any;
  constructor(public http: Http) {
    console.log('Hello HeroService');
  }

  load() {
    if (this.data) {
      return Promise.resolve(this.data);
    }


    return new Promise(resolve => {

      let md5 = new Md5();
      
      var timestamp = Number(new Date());
      var hash = Md5.hashStr(timestamp + 'ebd407c102ea3f1262b8dd370cfa04d4a132a867d8b23f3429d72898aaffd1a321761b4a');

      this.http.get(`https://gateway.marvel.com:443/v1/public/characters?ts=${timestamp}&orderBy=name&limit=10&apikey=d8b23f3429d72898aaffd1a321761b4a&hash=${hash}`)
        .map(res => res.json())
        .subscribe(data => {
          this.data = data;
          resolve(this.data);
        });
    });
  }

}

Como você pode ver no método acima, para acessar a API da Marvel, é preciso algumas credencias que podem ser encontradas neste link. Você irá utilizá-las para criar uma hash com a seguinte estrutura: (chave pública + chave privada+ timestamp) em um hash md5. Para essa ação, você precisará de um módulo chamado ts-md5, que pode ser baixado no portal NPM através do seguinte comando:

npm install ts-md5

O próximo passo é importar o provider na HomePage. Para isso, copie o código abaixo e cole no seu arquivo home.ts.

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

import { HeroService } from '../../providers/hero-service/hero-service';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  public obj: any;
  public heroes: any;
  
  constructor(public navCtrl: NavController, public heroService: HeroService) {
    this.getAllHeroes();
  }

  getAllHeroes() {
    this.heroService.load()
      .then(data => {
        this.obj = data;
        this.heroes = this.obj.data.results;
      });
  }

}

Agora, crie um componente para listar os heróis. Para isso, utilize um dos exemplos do site oficial do Ionic.

<ion-header>
  <ion-navbar>
    <ion-title>
      Heroes
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content class="home">
  <ion-list>
     <ion-item class="hero" (click)="getDescription(hero.id)" *ngFor="let hero of heroes">
      <ion-avatar item-left >
        <img src="{{hero.thumbnail.path}}.{{hero.thumbnail.extension}}">
      </ion-avatar>
      <h2>{{hero.name}}</h2>
    </ion-item> 
  </ion-list>
</ion-content>

Para testar o código, execute o comando abaixo no seu terminal:

ionic serve

Ele deve abrir a url http://localhost:8100/ no seu navegador. Veja a execução do código na imagem abaixo:

Lista de heróis Marvel

Pronto, você já tem uma lista com todos os heróis. Agora crie um evento para que o usuário possa clicar em cada personagem e ver os detalhes (nome, thumb e descrição). Todos esses dados devem ser requisitados de uma outra rota na API da Marvel.

O primeiro passo é atualizar o provider com essa nova requisição:

 getDescription(id: number) {
    return new Promise(resolve => {
      let md5 = new Md5();

      var timestamp = Number(new Date());
      var hash = Md5.hashStr(
        timestamp +
          "ebd407c102ea3f1262b8dd370cfa04d4a132a867d8b23f3429d72898aaffd1a321761b4a"
      );

      this.http
        .get(
          `https://gateway.marvel.com:443/v1/public/characters/${id}?ts=${timestamp}&orderBy=name&limit=20&apikey=d8b23f3429d72898aaffd1a321761b4a&hash=${hash}`
        )
        .map(res => res.json())
        .subscribe(data => {
          this.data = data;
          resolve(this.data);
        });
    });
  }

Depois você precisa de uma nova página para exibir esses novos dados. Para isso, execute no terminal o comando a seguir:

ionic generate page description

A execução irá criar uma nova página na solution. Depois disso, você precisa passar um id para a página buscar os dados do herói na API da Marvel. Para isso, atualize o seu arquivo home.ts com o código abaixo:

getDescription(id:number){
    console.log(id);
    this.navCtrl.push("DescriptionPage", {
      id: id
    })
  }

O próximo passo será atualizar o arquivo home.html e os arquivos description.ts e description.html.

home.html

<ion-content class="home">
  <ion-list>
     <ion-item class="hero" (click)="getDescription(hero.id)" *ngFor="let hero of heroes">
      <ion-avatar item-left >
        <img src="{{hero.thumbnail.path}}.{{hero.thumbnail.extension}}">
      </ion-avatar>
      <h2>{{hero.name}}</h2>
    </ion-item> 
  </ion-list>
</ion-content>

description.ts

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { HeroService } from '../../providers/hero-service/hero-service';
import { Hero } from '../../models/hero';

/**
 * Generated class for the DescriptionPage page.
 *
 * See https://ionicframework.com/docs/components/#navigation for more info on
 * Ionic pages and navigation.
 */

@IonicPage()
@Component({
  selector: 'page-description',
  templateUrl: 'description.html',
})
export class DescriptionPage {
  public id;
  public obj: any;
  public hero: Hero;
  

  constructor(public navCtrl: NavController, public navParams: NavParams, public heroService: HeroService) {
    this.id = navParams.get("id");
    
    this.hero = new Hero();
    this.heroService.getDescription(this.id)
    .then(data => {
      this.obj = data;
      console.log(this.obj);
      this.hero.name = this.obj.data.results[0].name; 
      this.hero.thumb = this.obj.data.results[0].thumbnail.path +"."+ this.obj.data.results[0].thumbnail.extension;
      this.hero.description =  this.obj.data.results[0].description;

      console.log(this.hero);
    });
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad DescriptionPage');
  }

}

description.html

<!--
  Generated template for the DescriptionPage page.
  See http://ionicframework.com/docs/components/#navigation for more info on
  Ionic pages and navigation.
-->
<ion-header>

  <ion-navbar>
    <ion-title>description</ion-title>
  </ion-navbar>

</ion-header>


<ion-content>
  
    <ion-card>
        
      <img src="{{hero.thumb}}"/>
  
      <ion-card-content>
        <ion-card-title>
            {{hero.name}}
        </ion-card-title>
        <p>
            {{hero.description}}
        </p>
      </ion-card-content>
    </ion-card>
  
  </ion-content>

E este será o resultado:

App Marvel

Foi simples? Você acabou de criar um APP em Ionic 3 consumindo dados de uma API externa. Caso tenha dúvida sobre algum passo, deixe seu comentário. Se quiser, veja o código final desse artigo no meu Git.