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
- Reqres: https://reqres.in/
- InfiniteScroll: http://ionicframework.com/docs/api/components/infinite-scroll/InfiniteScroll/
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!