Consultando a API do Blog.
E ai pessoal, vamos voltar para o desenvolvimento da nossa aplicação, devido ao pouco tempo que livre, resolvi que a série dará continuidade e será lançada toda quarta-feira pela manhã, e na parte 2 da nossa série estaremos consultando nossa API e consumindo as postagens do blog.
Para começar iremos editar o nosso arquivo index.html e deixar com a seguinte estrutura
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<title></title>
<link rel="manifest" href="manifest.json">
<!-- un-comment this code to enable service worker
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js')
.then(() => console.log('service worker installed'))
.catch(err => console.log('Error', err));
}
</script>-->
<link href="lib/ionic/css/ionic.css" rel="stylesheet">
<link href="styles/style.css" rel="stylesheet">
<!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above
<link href="css/ionic.app.css" rel="stylesheet">
-->
<!-- ionic/angularjs js -->
<script src="lib/ionic/js/ionic.bundle.js"></script>
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- your app's js -->
<script src="app/app.js"></script>
<script src="app/posts/posts.controller.js"></script>
<script src="app/posts/posts.service.js"></script>
<script src="app/menu/menu.controller.js"></script>
</head>
<body ng-app="appvila">
<ion-nav-view></ion-nav-view>
</body>
</html>
Estaremos importando os scripts de serviços e controladores dentro do index.html e o nome da nossa aplicação vai ser appvila dentro do ng-app.
Feito isso podemos agora criar nosso controlador de Posts e o serviço onde vamos tratar a chamada aos endpoints, assim vamos poder consumir o serviço no nosso controlador. Para o desenvolvimento da nossa aplicação estarei adotando o padrão de projeto proposto por John Papa, para você estudar mais sobre clique aqui, você encontrará tanto sobre angular 1 como angular 2.
Dentro do diretório app/posts iremos criar o arquivo chamado posts.service.js, ele será responsável por consultar nosso endpoints da nossa API do WordPress. Nele iremos escrever o seguinte código:
angular.module('posts.service', [])
.factory('postsService', postsService);
function postsService($http, $q) {
// interface
var service = {
posts: [],
getPosts: getPosts
};
return service;
// implementacao
function getPosts() {
var def = $q.defer();
$http.jsonp("http://localhost/appvila/wp-json/posts?filter[posts_per_page]=3&_embed&_jsonp=JSON_CALLBACK
")
.success(function(data) {
service.posts = data;
def.resolve(data);
})
.error(function() {
def.reject("Falha ao buscar posts");
});
return def.promise;
}
}
Vamos criar uma promise onde iremos retornar o resultado de nossa requisição em formato JSON em caso de sucesso ou falha em caso de erros. Falando um pouco sobre promise. Uma promise é um proxy para um valor não necessariamente conhecido quando a promessa é criada. Ele permite que você associe manipuladores com o valor de sucesso ou o motivo de falha de uma ação assíncrona. Isso permite que métodos assíncronos retornem valores como métodos síncronos: em vez de retornar imediatamente o valor final, o método assíncrono retorna uma promessa de fornecer o valor em algum ponto no futuro.
Uma promise está em um destes estados:
- pendente: estado inicial, não cumprido ou rejeitado.
- Preenchido: o que significa que a operação foi concluída com êxito.
- Rejeitada: significa que a operação falhou.
Com o nosso serviço criado, usaremos ele no controlador que será chamado na visão. Nosso arquivo posts.controller.js ficará assim:
angular.module('posts.controller', [])
.controller('PostsCtrl', PostsCtrl);
function PostsCtrl(postsService) {
var vm = this;
//usando nosso service para consultar as postagens
vm.posts = [];
vm.getPosts = function(){
postsService.getPosts()
.then(
function(posts){
for(var i=0; i < posts.length; i++){
vm.posts.push(posts[i]);
}
vm.posts = posts;
},
function(data) {
console.log('Falha ao consumir API.')
}
);
};
vm.getPosts();
}
No nosso controlador iremos injetar o serviço para podermos usá-lo, dentro da nossa promise estaremos preenchendo um vetor com o resultado das postagens, isso será usado posteriormente para fazer a paginação. Com nosso controlador pronto para pegar as postagens vamos agora implementar a visão, onde serão exibidos todas as postagens.
Agora vamos abrir o posts.html e escrever o seguinte código:
<ion-view view-title="Posts">
<ion-content>
<div ng-repeat="post in postsCtrl.posts" class="list card">
<div class="item item-avatar">
<img ng-src="{{post.author.avatar}}">
<h2 class="cor-texto">{{post.author.name}}</h2>
<p class="cor-texto">{{post.date}}</p>
</div>
<div class="item item-body">
<div>
<h2 ng-bind-html="post.title"></h2>
<img class="full-image" src="{{post.featured_image}}">
</div>
</div>
</div>
</ion-content>
</ion-view>
O código acima irá iterar sobre todas as postagens que foram retornadas e serão exibidas para gente na nossa rota principal, podemos ver o que nossa API retorna, usando a url diretamente no browser ou usando um programa para testar API’s chamado POSTMAN, com ele podemos visualizar o JSON que é retornado da API, que contém a seguinte estrutura:
Vamos deixar o controlador do menu criado, mas sem nenhuma função:
angular.module('menu.controller', [])
.controller('MenuCtrl', MenuCtrl);
function MenuCtrl(){
}
Estamos quase prontos para testar, vamos injetar nossos controladores e serviços no nosso módulo principal o app.js, ele ficará assim:
// Ionic Starter App
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('appvila', ['ionic', 'menu.controller', 'posts.controller', 'posts.service'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
if(window.cordova && window.cordova.plugins.Keyboard) {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
// Don't remove this line unless you know what you are doing. It stops the viewport
// from snapping when text inputs are focused. Ionic handles this internally for
// a much nicer keyboard experience.
cordova.plugins.Keyboard.disableScroll(true);
}
if(window.StatusBar) {
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('app', {
url: '/app',
abstract: true,
templateUrl: 'app/menu/menu.html',
controller: 'MenuCtrl as menuCtrl'
})
.state('app.posts', {
url: "/posts",
views: {
'menuContent': {
templateUrl: "app/posts/posts.html",
controller: 'PostsCtrl as postsCtrl'
}
}
});
$urlRouterProvider.otherwise('/app/posts');
});
Com todas as telas ajustadas, podemos testar nossa aplicação, acessando o diretório pelo terminal e usando o comando
$ ionic serve -l
O aplicativo terá essa aparência:

Podemos ver que a aplicação está funcionando e já é possível visualizar as postagens, porém só temos uma postagem em nosso blog, vamos criar mais algumas para podermos implementar a paginação com scroll infinito futuramente.

A página onde nos permite criar postagens é essa acima, criei algumas, vocês podem ficar a vontade para criar quantas quiserem. Podemos perceber que foram criadas exibidas apenas 3 postagens no nosso aplicativo, isso ocorreu por conta da url que passamos no nosso serviço, onde foi filtrado para trazer apenas 3 posts por página.
Vocês podem conferir como anda ficando nossa aplicação em https://github.com/viladosilicio/serie-ionic. Para ficar visivelmente melhor, vamos acessar o dashboard do nosso blog e criar uma categoria e um post novo.
