Laravel + AngularJS – sua primeira aplicação

Há alguns dias atrás vimos aqui no Clube dos Geeks um tutorial de como criar uma API RESTful usando o framework Laravel. Hoje faremos um post semelhante, mas a diferença é que faremos a comunicação entre a API Laravel e uma aplicação AngularJS.

Nossa API

Faremos uma API simples para cadastro, edição, listagem e exclusão de pessoas. Usando os métodos HTTP: POST, GET, PUT e DELETE.

Instalando o Laravel

Você pode usar o instalador do Larvel, executando o seguinte comando no bash:

$ composer global require “laravel/installer”

O Laravel será instalado de forma global. Depois você pode iniciar um aplicativo Laravel com o seguinte comando:

$ laravel new exemplo

Lembrando que exemplo será o nome da pasta de sua aplicação.

Criando projeto com composer

Você pode usar o comando create-project  do composer, que é a alternativa mais indicada para usuários Windows. Veja como fazer:

$ composer create-project laravel/laravel exemplo --prefer-dist

Será criada a pasta exemplo e dentro dela uma série de pastas e arquivos do Laravel. As principais pastas que iremos usar serão app config.

Configurando o Virtual Host

Você precisa configurar um virtual host para apontar para a pasta da sua aplicação de exemplo. Farei este exemplo usando WAMP instalado obviamente em um computador com sistema operacional Windows.

Arquivos hosts

Primeiro abra o arquivo hosts do Windows, que está em C:\Windows\System32\drivers\etc e adicione o seguinte no final:

127.0.0.1    laravel.exemplo

laravel.exemplo será o domínio para acessar nossa api.

Virtual host

Se você estiver usando Windows e WAMP o arquivo de virtual hosts estará emC:\wamp\bin\apache\apache2.4.17\conf\extra, tenha atenção à versão do apache.

Adicione o seguinte no arquivo:

Você deve colocar o caminho da sua API apontando para a pasta public, por exemplo:C:/wamp/www/exemplo/public

Acesse o endereço laravel.exemplo no seu navegador. Você verá a tela de demonstração do Laravel.

Lembrando a configuração do Virtual Hosts pode ser diferente em determinados sistemas operacionais.

Banco de dados

Crie um banco de dados chamado api para que possamos usar no nosso exemplo.

CREATE DATABASE api;

Configuração

Abra o arquivo database.php que está dentro da pasta config da sua aplicação Laravel, e você verá um vetor com diversas chaves, uma delas será a connections onde você vai encontrar exemplos de conexões de bancos de dados SQLite, MySQL e PostgreSQL. Usaremos MySQL, então modifique as configurações para o seguinte:

O Laravel conta com uma classe pronta para execução de queries e comandos no banco de dados. Em breve veremos mais sobre.

Criando tabela

O Laravel conta com uma interface de linha de comandos chamada Artisan, que serve para ajudar na criação de controllers, migração de banco de dados, etc. Você pode ter mais detalhes na documentação oficial.

Usaremos o Artisan para criar nossa tabela. Volte para o bash ou prompt de comando e execute o seguinte comando dentro da pasta raiz da aplicação laravel criada.

$ php artisan make:migration table_pessoas

Será criado um arquivo dentro da pasta database/migrations/ o nome dele será composto pela data e hora atual mais o termo informado table_pessoas e ele terá extensão .php.

Abra esse arquivo e veja que ele é basicamente uma classe que conta com dois métodos (up down) sem conteúdo algum dentro deles.

Adicionaremos o seguinte código dentro do método up():

Schema::create('pessoas', function (Blueprint $table) {
    $table->increments('id');
    $table->string('nome');
    $table->string('email');
    $table->timestamps();
});

E no método down() adicionaremos o seguinte:

Schema::drop('pessoas');

Você pode apagar os demais arquivos dentro da pasta migrations se desejar.

Agora execute o seguinte comando no bash:

$ php artisan migrate

Você verá que será criada a tabela pessoas no seu banco de dados.

Criando Controller

Usando o prompt de comando execute o seguinte comando:

$ php artisan make:controller PessoaController

Dentro da pasta app/Http/Controllers você encontrará o arquivo PessoaController.php com o seguinte conteúdo:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

class PessoaController extends Controller
{
    //
}

Nós iremos edita-lo, para que fique assim:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;

use DB; // para usar a classe DB

class PessoaController extends Controller
{
	// Listando pessoas
    public function lista()
    {
    	return DB::table('pessoas')
    		->get();
    }

    // Cadastrando Pessoa
    public function novo(Request $request)
    {
    	$data = sizeof($_POST) > 0 ? $_POST : json_decode($request->getContent(), true); // Pega o post ou o raw

    	return DB::table('pessoas')
    		->insertGetId($data);
    }

    // Editando pessoas
	public function editar($id, Request $request){
		$data = sizeof($_POST) > 0 ? $_POST : json_decode($request->getContent(), true); // Pega o post ou o raw
 
		$res = DB::table('pessoas')
			->where('id',$id)
			->update($data);
 
		return ["status" => ($res)?'ok':'erro'];
	}

	// Excluindo pessoa
	public function excluir($id)
	{
		$res = DB::table('pessoas')
			-> where('id',$id)
			-> delete();
			
		return ["status" => ($res)?'ok':'erro'];
	}
}

Veja na linha 9 que evocamos a classe DB para usar o banco de dados;

Nas linhas 23 31 é verificado se existe dados enviados usando form-data ou se eles foram enviados usando raw por exemplo.

Rotas

Para usar os métodos do Controller temos que usar rotas, que usam as requisições HTTP e direcionam para os controllers e métodos corretos.

No Laravel as rotas estão no arquivo app/Http/routes.php, adicione as seguintes rotas nele:

Route::get('/', function () {
    return view('index');
});

Route::group(['prefix' => 'api'], function()
{
	Route::get('pessoas', 'PessoaController@lista');
	Route::post('pessoas', 'PessoaController@novo');
	Route::put('pessoa/{id}', 'PessoaController@editar');
	Route::delete('pessoa/{id}', 'PessoaController@excluir');
});

A API está pronta, agora partiremos para o desenvolvimento do lado da aplicação AngularJS.

Nossa aplicação

Se você é novo em AngularJS, sugiro que veja alguns posts presentes no site Awesome-br.

Instalando dependências

Pelo bash ou prompt de comando acesse a pasta de sua aplicação Laravel e depois a pasta public usando o comando cd. (Ex.: cd aplicacao/public).

Execute o seguinte comando para instalar as dependências por meio do NPM:

$ npm install angular bootstrap jquery@1.9.1

A pasta node_modules  será criada dentro da pasta public e dentro dela estarão as dependências.

Criando view

Na pasta resources/views crie um arquivo com o nome index.php. Esta será a página principal da nossa aplicação. Este arquivo terá o seguinte conteúdo:

<!DOCTYPE html>
<html ng-app="cdg">
<head>
	<title>Cadastro de Pessoas</title>
	<link rel="stylesheet" type="text/css" href="node_modules/bootstrap/dist/css/bootstrap.css">

	<script type="text/javascript" src="node_modules/jquery/jquery.js"></script>
	<script type="text/javascript" src="node_modules/bootstrap/dist/js/bootstrap.js"></script>

	<!-- Angular -->
	<script type="text/javascript" src="node_modules/angular/angular.js"></script>

	<!-- App -->
	<script type="text/javascript" src="app/app.js"></script>
</head>
<body ng-controller="pessoaController">
	<div class="container" ng-init="listar()">
		<div class="row">
			<div class="col-md-12">
				<h1>Cadastro de Pessoas</h1>
			</div>
		</div>
		<hr>
		<div class="row">
			<div class="col-md-6">
				<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#myModal">Nova Pessoa</button>
			</div>
			<div class="col-md-6">
				<input class="form-control" ng-model="pesquisar">
			</div>
		</div>
		<hr>
		<div class="row">
			<div class="col-md-12">
				<table class="table table-striped">
					<thead>
						<tr>
							<th>#</th>
							<th>Nome</th>
							<th>E-mail</th>
							<th></th>
						</tr>
					</thead>
					<tbody>
						<tr ng-repeat="pessoa in pessoas | filter: pesquisar">
							<td>{{pessoa.id}}</td>
							<td>{{pessoa.nome}}</td>
							<td>{{pessoa.email}}</td>
							<td>
								<button class="btn btn-info btn-xs" ng-click="editar(pessoa)">Editar</button>
								<button class="btn btn-danger btn-xs" ng-click="excluir(pessoa)">Excluir</button>
							</td>
						</tr>
					</tbody>
				</table>
			</div>
		</div>
	</div>

	<!-- Modal -->
	<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
		<div class="modal-dialog" role="document">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
					<h4 class="modal-title" id="myModalLabel">Cadastro de Pessoa</h4>
				</div>
				<div class="modal-body">
					<div class="form-group">
						<label>Nome:</label>
						<input type="text" class="form-control" ng-model="pessoa.nome">
					</div>
					<div class="form-group">
						<label>E-mail:</label>
						<input type="email" class="form-control" ng-model="pessoa.email">
					</div>
				</div>
				<div class="modal-footer">
					<button type="button" class="btn btn-default" data-dismiss="modal" ng-click="pessoa = {}">Cancelar</button>
					<button type="button" class="btn btn-primary" ng-click="salvar()">Salvar</button>
				</div>
			</div>
		</div>
	</div>

</body>
</html>

Note na linha 14 que chamamos o arquivo app.js que deve ser criado na pasta public.

app.js

Dentro da pasta public crie uma pasta chamada app e dentro dela um arquivo app.js. Nele estará o nosso aplicativo AngularJS.

'use strict';
var app = angular.module('cdg',[]);

// Service
app.factory('pessoaService',function($http) {
	return {
		lista: function(){
			return $http.get('/api/pessoas');
		},
		cadastra: function(data){
			return $http.post('/api/pessoas', data);
		},
		edita: function(data){
			var id = data.id;
			delete data.id;
			return $http.put('/api/pessoa/'+id, data);
		},
		exclui: function(id){
			return $http.delete('/api/pessoa/'+id)
		}
	}
});

// Controller
app.controller('pessoaController', function($scope, pessoaService) {
	$scope.listar = function(){
		pessoaService.lista().success(function(data){
			$scope.pessoas = data;
		});
	}

	$scope.editar = function(data){
		$scope.pessoa = data;
		$('#myModal').modal('show');
	}

	$scope.salvar = function(){
		if($scope.pessoa.id){
			pessoaService.edita($scope.pessoa).success(function(res){
				$scope.listar();
				$('#myModal').modal('hide');
			});
		}else{
			pessoaService.cadastra($scope.pessoa).success(function(res){
				$scope.listar();
				$('#myModal').modal('hide');
			});
		}
	}

	$scope.excluir = function(data){
		if(confirm("Tem certeza que deseja excluir?")){
			pessoaService.exclui(data.id).success(function(res){
				$scope.listar();
			});
		}
	}
});

Concluindo

Para testar basta acessar o endereço laravel.exemplo no seu navegador. Quaisquer erros, problemas ou sugestões deixe um comentário.

Você pode ter acesso ao código fonte deste exemplo no Git Hub. E ver mais sobre AngularJS ou Angular 2 aqui no Clube dos Geeks.

Curta nossa página no Facebook e acompanhe nosso post.

Jayr Alencar

Doutorando em Ciências da Computação no Centro de Informática da Universidade Federal do Pernambuco (CIn - UFPE); Mestre pela mesma instituição; Formado em Análise e Desenvolvimento de Sistemas; Católico; Fã de O Senhor do Anéis.

Você pode gostar...

10 Resultados

  1. Carlos Henrique disse:

    o meu não aparece nada, só as chaves do json []

  2. Marcos disse:

    Amigão e quanto a segurança e autenticação, tudo bem que o laravel ja faz tratamento e escape automático, da pra confiar de olhos fechados nisso?

  3. Kirlian Silvestre disse:

    adorei o texto, infelizmente encontrei alguns problemas:
    1 – configurando o virtual hosts, a pasta public ficou inacessivel, retornando “acesso proibido” (estou usando xampp com windows), resolvi tirando o virtual host e acessando diretamente a pasta public.
    2 – tb tive problemas com a função listar do controller no angular, resolvi trocando o escopo da função para: $scope.pessoas = data.data;
    3 – o problema que ainda não resolvi, foi um no editar do Laravel, que ele dá o seguinte erro na linha do where.
    Call to undefined method Illuminate\Database\Query\Builder::update()
    se puderem me ajudar com isso, agradeço, pois estou aprendendo agora a mexer com laravel e fiquei totalmente perdido nisso, pois vi que existe a função no Builder.php.

  4. Emerson MS disse:

    Sei que esse post é antigo mas segue uma correção para a lista aparecer. Em vez de utilizar o .success utilize o .then, no meu caso fiz assim para funcionar:
    $scope.listar = function() {
    pessoaService.lista().then(function(response){
    $scope.pessoas = response.data;
    });
    }

Deixe um comentário para Kirlian Silvestre Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *