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!
Parabéns, to começando agora e ja vou fazer essa aula
Valeu Elias! Qualquer dúvida posta ai!
Adorei o site, tudo que eu estava precisando para iniciar no ionic,
Parabéns.
Valeu Gabriel! Qualquer dúvida é só fala!
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’;
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
Fala Philippe, blz?
Você está carregando as paginas com lazy loading?
Consegue compartilhar seu código no GitHub para eu ver?
Att
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!
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
Fala Meg Rodrigues, blz?
Muito maneiro seus aplicativos!
Obrigado por compartilhar! =]
Valeu!
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??