É possível realizar operação de remoção de livros através do uso do método DELETE, conforme abaixo:
1-) method-override:
Em alguns navegadores (principalmente os mais antigos), não é possível utilizar o método DELETE diretamente pela propriedade “method” da tag “form” do html, conforme abaixo:
...
<!-- Em alguns navegadores, esse recurso não funcona... -->
<form action=“/remove” method=“delete”>
...
</form>
...
Quando o navegador não suporta esse tipo de operação, o comportamento padrão adotado por este é fazer um GET para a action informada, o que certamente não é nossa intenção.
O nodejs possui um recurso que oferece uma alternativa à esses casos, chamado de “method-override”, que também faz parte do Express. Uma das maneiras de utiliza-lo é enviando uma requisição POST para a action do form com um parâmetro a mais, nomeado de “_method”, cujo valor definido (“delete” por exemplo) será o verdadeiro método chamado pelo nodejs (exemplo mais adiante). Para utiliza-lo, primeiramente precisamos adicionar o uso do recurso “method-override” na nossa aplicação, conforme abaixo:
// ./config/express.js
var express = require('express');
var load = require('express-load');
var bodyParser = require('body-parser’);
// Mais um require aqui...
var methodOverride = require('method-override');
module.exports = function() {
var app = express();
app.set('view engine', 'ejs');
app.set('views', './app/views');
app.use(bodyParser.urlencoded({extended : true}));
// É importante que essa chamada fique depois do uso do bodyParser,
// pois somente após os parâmetros da requisição serem devidamente
// incluídos nos devidos objetos é que o method_override poderá realizar
// “sua mágica”.
app.use(methodOverride('_method'));
load('routes', {cwd : 'app'})
.then('infra')
.into(app);
return app;
}
Existem outras formas de sobrescrever um método HTTP pelo com o method-override, segue documentação para mais detalhes: https://github.com/expressjs/method-override .
2-) Preparando o HTML:
Agora precisamos preparar nosso HTML para incluir a funcionalidade de remoção de livros. Criamos mais uma coluna na nossa tabela de livros, com um botão para remoção do registro.
<!—- ./app/views/produtos/lista.ejs -—>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<table border="1px">
<tr>
<td>Id</td>
<td>Titulo</td>
<td>Descricao</td>
<td>Preço</td>
<td>Acao</td>
</tr>
<% for(var i = 0; i < lista.length; i++) {%>
<tr>
<td><%= lista[i].id %></td>
<td><%= lista[i].titulo %></td>
<td><%= lista[i].descricao %></td>
<td><%= lista[i].preco %></td>
<td>
<!—- Fingimos realizar uma requisição POST, passando na URL da action o parâmetro “_method” com valor “DELETE" -—>
<form action="/produtos?_method=DELETE" method="post">
<input type="hidden" name="id" value="<%= lista[i].id %>" />
<input type="submit" value="Apaga" />
</form>
</td>
</tr>
<% } %>
</table>
</body>
</html>
Perceba que esse botão precisa estar envolto de um form, com o atributo “method" como POST (este será substituído pelo DELETE pelo method-override, conforme descrito no passo anterior) e com o parâmetro “_method” na action com o valor DELETE (caso quiséssemos realizar um PUT, bastaria mudar esse valor para "PUT”).
3-) Ajustando nosso controller:
Agora que já realizamos os “setup” necessário na nossa aplicação, precisamos criar uma rota no nosso controller “produtos.js" que atenda o método DELETE no nosso recurso /produtos. Segue abaixo a definição da rota:
// ./app/routes/produtos.js
// outras rotas...
// Devido ao valor “DELETE" que passamos no parâmetro “_method”, o method-override tratou a requisição
// para nós e chamou o método DELETE ao invés do POST original.
app.delete('/produtos', function(req, res) {
var connection = app.infra.connectionFactory();
var produtoDAO = new app.infra.ProdutoDAO(connection);
var id = req.body.id;
produtoDAO.remove(id, function(err, result) {
if(err) {
console.log(err);
}
res.redirect('/produtos');
});
connection.end();
});
4-) Por fim, o DAO:
Por último, basta definir o método “remove” no nosso arquivo ProdutoDAO.js. Segue abaixo:
// ./app/infra/ProdutoDAO.js
// outros métodos..
ProdutoDAO.prototype.remove = function(id, callback) {
this._connection.query('delete from livros where id = ?', [id], callback);
}
5-) Considerações:
Embora essa solução seja só um “workaround”, ela garante compatibilidade da aplicação com navegadores antigos, compensando seu uso. Caso alguém tenha feito de uma maneira diferente, não deixe de compartilhar =).