Consumindo API REST com Ionic – O guia absolutamente completo

Nessa vídeo aula eu vou mostrar como fazer requisições HTTP a uma API REST.
Esse exemplo é valido tanto para aplicações feitas com Angular e Ionic.
E também como paginar os resultados utilizando o InfiniteScroll.

 

O que é API REST

REST significa Representational State Transfer, em português Transferência de Estado Representacional e é um conjunto arquiteturas mais moderno para construção de webservices.

 

Criando uma aplicação de exemplo

Será criado uma aplicação onde eu vou mostrar como criar uma conta, efetuar um login e incluir/alterar/excluir/consultar um usuário.

Vou usar também a API Reqres que prove vários exemplos de endpoints com dados fake.

E vou mostrar como paginar os dados utilizando o componente InfiniteScroll do Ionic.

O passo a passo abaixo é o mesmo mostrado no vídeo.

  • Passo 1: Criar o aplicativo.
  • Passo 2: Configurar o aplicativo para requisições HTTP.
  • Passo 3: Ajustar a Home para exibir os botões para os exemplos.
  • Passo 4: Criar o provider a criação de conta/login/CRUD de usuários.
  • Passo 5: Criar a página de criação de conta
  • Passo 6: Criar a página de login.
  • Passo 7: Criar a página para listar usuários.
  • Passo 8: Criar a página para incluir/alterar um usuário.
  • Passo 9: Criar a pagina para exibir um usuário.

 

Passo 1: Criar o aplicativo

ionic start NOME_DO_APP blank

 

Passo 2: Configurar o aplicativo para requisições HTTP

Registrar o HttpModule na parte de imports.

Arquivo 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 { UsersProvider } from '../providers/users/users';

import { HttpModule } from '@angular/http';

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

 

Passo 3: Ajustar a Home para exibir os botões para os exemplos

Arquivo home.ts

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

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

  constructor(public navCtrl: NavController) { }

  openCreateAccount() {
    this.navCtrl.push('CreateAccountPage');
  }

  openLogin() {
    this.navCtrl.push('LoginPage');
  }

  openListUsers() {
    this.navCtrl.push('UserListPage');
  }
}

 

Arquivo home.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

  <h1 text-center margin-bottom>Exemplo de API REST</h1>

  <button ion-button block (click)="openCreateAccount()">Criar conta</button>
  <button ion-button block (click)="openLogin()">Login</button>
  <button ion-button block (click)="openListUsers()">CRUD de usuários</button>

</ion-content>

 

Passo 4: Criar o provider a criação de conta/login/CRUD de usuários

ionic g provider users

 

Arquivo users.ts

import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';

@Injectable()
export class UsersProvider {
  private API_URL = 'https://reqres.in/api/'

  constructor(public http: Http) { }

  createAccount(email: string, password: string) {
    return new Promise((resolve, reject) => {
      var data = {
        email: email,
        password: password
      };

      this.http.post(this.API_URL + 'register', data)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  login(email: string, password: string) {
    return new Promise((resolve, reject) => {
      var data = {
        email: email,
        password: password
      };

      this.http.post(this.API_URL + 'login', data)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  getAll(page: number) {
    return new Promise((resolve, reject) => {

      let url = this.API_URL + 'users/?per_page=10&page=' + page;

      this.http.get(url)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  get(id: number) {
    return new Promise((resolve, reject) => {
      let url = this.API_URL + 'users/' + id;

      this.http.get(url)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  insert(user: any) {
    return new Promise((resolve, reject) => {
      let url = this.API_URL + 'users/';

      this.http.post(url, user)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  update(user: any) {
    return new Promise((resolve, reject) => {
      let url = this.API_URL + 'users/' + user.id;
      let data = {
        "first_name": user.first_name,
        "last_name": user.last_name
      }

      this.http.put(url, user)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }

  remove(id: number) {
    return new Promise((resolve, reject) => {
      let url = this.API_URL + 'users/' + id;

      this.http.delete(url)
        .subscribe((result: any) => {
          resolve(result.json());
        },
        (error) => {
          reject(error.json());
        });
    });
  }
}

 

Passo 5: Criar a página de criação de conta

ionic g page create-account

 

Arquivo create-account.ts

import { UsersProvider } from './../../providers/users/users';
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ToastController } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-create-account',
  templateUrl: 'create-account.html',
})
export class CreateAccountPage {
  model: User;

  constructor(public navCtrl: NavController, public navParams: NavParams, private toast: ToastController, private userProvider: UsersProvider) {
    this.model = new User();
    this.model.email = 'sydney@fife';
    this.model.password = 'pistol';
  }

  createAccount() {
    this.userProvider.createAccount(this.model.email, this.model.password)
      .then((result: any) => {
        this.toast.create({ message: 'Usuário criado com sucesso. Token: ' + result.token, position: 'botton', duration: 3000 }).present();

        //Salvar o token no Ionic Storage para usar em futuras requisições.
        //Redirecionar o usuario para outra tela usando o navCtrl
        //this.navCtrl.pop();
        //this.navCtrl.setRoot()
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao criar o usuário. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });
  }
}

export class User {
  email: string;
  password: string;
}

 

Arquivo create-account.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

  <h1 text-center>Exemplo de criação de conta</h1>

  <ion-list>
    <ion-item>
      <ion-label stacked>Email</ion-label>
      <ion-input type="text" name="email" [(ngModel)]="model.email"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label stacked>Senha</ion-label>
      <ion-input type="password" name="password" [(ngModel)]="model.password"></ion-input>
    </ion-item>
  </ion-list>

  <button ion-button block (click)="createAccount()" color="primary">Criar conta</button>

</ion-content>

 

Passo 6: Criar a página de login

ionic g page login

 

Arquivo login.ts

import { UsersProvider } from './../../providers/users/users';
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ToastController } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-login',
  templateUrl: 'login.html',
})
export class LoginPage {
  model: User;

  constructor(public navCtrl: NavController, public navParams: NavParams, private toast: ToastController, private userProvider: UsersProvider) {
    this.model = new User();
    this.model.email = 'sydney@fife';
    this.model.password = 'pistol';
  }

  login() {
    this.userProvider.login(this.model.email, this.model.password)
      .then((result: any) => {
        this.toast.create({ message: 'Usuário logado com sucesso. Token: ' + result.token, position: 'botton', duration: 3000 }).present();

        //Salvar o token no Ionic Storage para usar em futuras requisições.
        //Redirecionar o usuario para outra tela usando o navCtrl
        //this.navCtrl.pop();
        //this.navCtrl.setRoot()
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao efetuar login. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });
  }
}

export class User {
  email: string;
  password: string;
}

 

Arquivo login.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

  <h1>Exemplo de login</h1>

  <ion-list>
    <ion-item>
      <ion-label stacked>Email</ion-label>
      <ion-input type="text" name="email" [(ngModel)]="model.email"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label stacked>Senha</ion-label>
      <ion-input type="password" name="password" [(ngModel)]="model.password"></ion-input>
    </ion-item>
  </ion-list>

  <button ion-button block (click)="login()" color="primary">Logar</button>

</ion-content>

 

Passo 7: Criar a página para listar usuários

ionic g page user-list

 

Arquivo user-list.ts

import { UsersProvider } from './../../providers/users/users';
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ToastController, InfiniteScroll } from 'ionic-angular';
import { ViewChild } from '@angular/core';

@IonicPage()
@Component({
  selector: 'page-user-list',
  templateUrl: 'user-list.html',
})
export class UserListPage {
  users: any[];
  page: number;
  @ViewChild(InfiniteScroll) infiniteScroll: InfiniteScroll;

  constructor(public navCtrl: NavController, public navParams: NavParams, private toast: ToastController, private userProvider: UsersProvider) { }

  ionViewDidEnter() {
    this.users = [];
    this.page = 1;
    this.infiniteScroll.enable(true);
    this.getAllUsers(this.page);
  }

  getAllUsers(page: number) {
    this.userProvider.getAll(page)
      .then((result: any) => {
        for (var i = 0; i < result.data.length; i++) {
          var user = result.data[i];
          this.users.push(user);
        }

        if (this.infiniteScroll) {
          this.infiniteScroll.complete();
          if (this.users.length == result.total) {
            this.infiniteScroll.enable(false);
          }
        }
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao listar os usuários. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });
  }

  getUsers() {
    setTimeout(() => {
      this.page += 1;
      this.getAllUsers(this.page);
    }, 500);
  }

  openUser(id: number) {
    this.userProvider.get(id)
      .then((result: any) => {
        this.navCtrl.push('UserDetailPage', { user: result.data });
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao recuperar o usuário. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });

  }

  openCreateUser() {
    this.navCtrl.push('UserEditPage');
  }

  openEditUser(id: number) {
    this.userProvider.get(id)
      .then((result: any) => {
        this.navCtrl.push('UserEditPage', { user: result.data });
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao recuperar o usuário. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });
  }

  deleteUser(user: any) {
    this.userProvider.remove(user.id)
      .then((result: any) => {
        let index = this.users.indexOf(user);
        this.users.splice(index, 1);

        this.toast.create({ message: 'Usuário excluído com sucesso.', position: 'botton', duration: 3000 }).present();
      })
      .catch((error: any) => {
        this.toast.create({ message: 'Erro ao excluir o usuário. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      });
  }
}

 

Arquivo user-list.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

  <ion-list>
    <ion-item-sliding *ngFor="let user of users">
      <ion-item (click)="openUser(user.id)">
        <ion-avatar item-start>
          <img src="{{ user.avatar }}">
        </ion-avatar>
        <h2>{{ user.first_name }} {{ user.last_name }}</h2>
      </ion-item>

      <ion-item-options side="left">
        <button ion-button color="primary" (click)="openEditUser(user.id)">
            <ion-icon name="create"></ion-icon>
            Editar
          </button>
        <button ion-button color="danger" (click)="deleteUser(user)">
            <ion-icon name="trash"></ion-icon>
            Excluir
          </button>
      </ion-item-options>
    </ion-item-sliding>

  </ion-list>

  <ion-infinite-scroll (ionInfinite)="getUsers($event)">
    <ion-infinite-scroll-content loadingSpinner="bubbles" loadingText="Aguarde...">
    </ion-infinite-scroll-content>
  </ion-infinite-scroll>

  <ion-fab right bottom>
    <button ion-fab color="light" (click)="openCreateUser()"><ion-icon name="add"></ion-icon></button>
  </ion-fab>
</ion-content>

 

Passo 8: Criar a página para incluir/alterar um usuário

ionic g page user-edit

 

Arquivo user-edit.ts

import { UsersProvider } from './../../providers/users/users';
import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ToastController } from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-user-edit',
  templateUrl: 'user-edit.html',
})
export class UserEditPage {
  model: User;

  constructor(public navCtrl: NavController, public navParams: NavParams, private toast: ToastController, private userProvider: UsersProvider ) {
    if (this.navParams.data.user) {
      this.model = this.navParams.data.user;
    } else {
      this.model = new User();
    }
  }

  save() {
    this.saveUser()
      .then(() => {
        this.toast.create({ message: 'Usuário salvo com sucesso.', position: 'botton', duration: 3000 }).present();
        this.navCtrl.pop();
      })
      .catch((error) => {
        this.toast.create({ message: 'Erro ao salvar o usuário. Erro: ' + error.error, position: 'botton', duration: 3000 }).present();
      })
  }

  private saveUser() {
    if (this.model.id) {
      return this.userProvider.update(this.model);
    } else {
      return this.userProvider.insert(this.model);
    }
  }

}

export class User {
  id: number;
  first_name: string;
  last_name: string;
}

 

Arquivo user-edit.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>

  <ion-list>
    <ion-item>
      <ion-label stacked>Nome</ion-label>
      <ion-input type="text" name="first_name" [(ngModel)]="model.first_name"></ion-input>
    </ion-item>

    <ion-item>
      <ion-label stacked>Sobrenome</ion-label>
      <ion-input type="text" name="last_name" [(ngModel)]="model.last_name"></ion-input>
    </ion-item>
  </ion-list>

  <button ion-button block (click)="save()" color="primary">Salvar</button>

</ion-content>

 

Passo 9: Criar a pagina para exibir um usuário

ionic g page user-detail

 

Arquivo user-detail.ts

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

@IonicPage()
@Component({
  selector: 'page-user-detail',
  templateUrl: 'user-detail.html',
})
export class UserDetailPage {
  user: any;

  constructor(public navCtrl: NavController, public navParams: NavParams) {
    this.user = this.navParams.data.user;
  }

}

 

Arquivo user-detail.html

<ion-header>
  <ion-navbar>
    <ion-title>
      Ionic Rest Api Example
    </ion-title>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <div text-center>
      <img src="{{ user.avatar }}">
    <h1>{{ user.first_name }} {{ user.last_name }}</h1>
  </div>
</ion-content>

 

Clique no botão abaixo para ver o código fonte gerado nessa aula

 

[button style=”btn-primary btn-lg” type=”link” target=”true” title=”Código fonte gerado na aula” link=”https://github.com/fabricadecodigo/IonicConsumeRestApiExample” linkrel=””]

 

Referências

 

Gostou desse artigo? Aproveite e curta e compartilhe para que mais pessoas possam também visualiza-lo!

Ainda ficou alguma dúvida ou tem alguma sugestão? Deixa aí nos comentários!

11 comentários em “Consumindo API REST com Ionic – O guia absolutamente completo”

  1. Gabriel Carvalho

    Adorei o site, tudo que eu estava precisando para iniciar no ionic,
    Parabéns.

  2. olá boa noite, muito bom material…
    só fiquei com uma duvida, como pego os dados vindo do form, no caso os this.model.email = ‘sydney@fife’; this.model.password = ‘pistol’;

  3. Muito boa a aula Felipe.

    Poderia me dar um help?
    Estou tendo este erro ao rodar a aplicação.

    Error: Uncaught (in promise): invalid link: CreateAccountPage
    at c (http://localhost:8100/build/polyfills.js:3:19752)
    at Object.reject (http://localhost:8100/build/polyfills.js:3:19174)
    at NavControllerBase._fireError (http://localhost:8100/build/vendor.js:48008:16)
    at NavControllerBase._failed (http://localhost:8100/build/vendor.js:48001:14)
    at http://localhost:8100/build/vendor.js:48048:59
    at t.invoke (http://localhost:8100/build/polyfills.js:3:14976)
    at Object.onInvoke (http://localhost:8100/build/vendor.js:4979:33)
    at t.invoke (http://localhost:8100/build/polyfills.js:3:14916)
    at r.run (http://localhost:8100/build/polyfills.js:3:10143)
    at http://localhost:8100/build/polyfills.js:3:20242
    Ionic Framework: 3.9.2

  4. Fala Leonay, desculpa não responder antes, apenas hoje vi seu comentário.
    De qualquer maneira,

    Tanto para pegar, como para passar os dados para o formulário é só preencher as propriedades que vão no [(ngModel)], no exemplo desse artigo estou usando a propriedade model, então ficaria this.model.email, exatamente como estou usando no método createAccount da página CreateAccountPage.

    Se eu não tivesse criado o código

    this.model.email = ‘sydney@fife’;
    this.model.password = ‘pistol’;

    Quando o clicasse no botão para criar a conta eu iria conseguir acessar os valores digitados no formulário através do this.model.email ou this.model.password

    Valeu!

  5. Meg Rodrigues

    Conteúdo muito bom, aproveito aqui para compartilhar minha experiência com o ionic, desenvolvi dois aplicativos hibridos, um é um jogo da memória onde vc mesmo cria seus tabuleiros com suas imagens de galeria, se quiserem dar uma olhada e me dar a opinião de vcs, está na playstore e é gratuito, segue o link =)
    https://play.google.com/store/apps/details?id=com.i9.memoriav1
    o outro é um aplicativo para vendedores criarem seus catalogos de produtos:
    https://play.google.com/store/apps/details?id=com.i9.catalogov1

  6. Muito bom amigo, podeira fazer um exemplo implementando a função de salvar esses dados em um banco sqlite local pra uso offline caso não tenha conexão??

Comentários encerrados.