Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Dúvida no Ex. 2 da Aula 3 - Verbos http

Estou tentando implementar a function delete que faz parte dos verbos http, entretanto, não estou conseguindo. Meu produtos.js e lista.ejs estão assim:

/*produtos.js*/

app.delete('/produtos/:id', function(req, res){
    var produtos = req.body;
    var id = req.params.id;

    var connection = app.infra.connectionFactory();
    var produtosDAO = new app.infra.ProdutosDAO(connection);

    produtosDAO.deleta(id, function(err, results){
        res.redirect('/produtos');
    });

    console.log("acabou a function");
});
/*lista.ejs*/
<tr>
    <td><%=lista[i].id%></td>
    <td><%=lista[i].titulo%></td>
    <td><%=lista[i].descricao%></td>
    <td><%=lista[i].preco%></td>
    <td><a href="/produtos/<%=lista[i].id%>">Deletar</a></td>
</tr>
8 respostas

Marllon, links no html obrigatoriamente enviam requisições GET. Para implementar uma requisição DELETE utilize por exemplo a API XMLHTTPRequest ou o jQuery com o comando .ajax();

Marllon,

se você utilizar a barra de endereço do navegador não irá funcionar. Você pode utilizar a extensão do chrome Postman na qual você altera o método de requisição. Ela é bem completa!

Tentei deletar conforme o exercicio.

(*obs = Sem aspas simples)

lista.ejs ... '<'a hef="/produtos/deletar/:id='<'%=lista[i].id&'">'deletar'<'/a> ... produtos.js ... app.get("/produtos/deletar/:id", function(req, res){

var id = req.params.id; id = id.replace(":", "");

var connection = app.infra.connectionFactory();//conectando com o banco var produtosDao = new app.infra.ProdutosDAO(connection);

produtosDao.deletar(id, function(){ res.redirect("/produtos"); }); connection.end();

}); ... ProdutosDAO.js ... ProdutosBanco.prototype.deletar = function(id, callback){ this._connection.query("delete from livros where " + id, callback); } ...

Confesso que apanhei bem...

solução!

Tentei deletar conforme o exercicio.

(*obs = Sem aspas simples)

lista.ejs

'<'a hef="/produtos/deletar/:id='<'%=lista[i].id&'">'deletar'<'/a>

produtos.js

app.get("/produtos/deletar/:id", function(req, res){

var id = req.params.id; id = id.replace(":", "");

var connection = app.infra.connectionFactory();//conectando com o banco var produtosDao = new app.infra.ProdutosDAO(connection);

produtosDao.deletar(id, function(){ res.redirect("/produtos"); }); connection.end();

}); ProdutosDAO.js

ProdutosBanco.prototype.deletar = function(id, callback){        this._connection.query("delete from livros where " + id, callback);
    }

Confesso que apanhei bem...

Só consegui copiado o arquivo do Santiago, muito complicado! Apanhei um monte também e não entendi muito bem.

Foi como o Allain Magyar disse, links html usam o verbo GET.

Pra testar com outro verbo vcs poderiam criar um form com o method (post por exemplo).

É 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 =).

Luiz, sensacional a dica! Muito obrigado!

Mas pelo que andei lendo, até então o HTML só permite GET ou POST como valores para o atributo method.

Dê uma olhada: - https://www.w3.org/TR/html401/interact/forms.html#h-17.13.1 - https://www.w3schools.com/TAGS/att_form_method.asp

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software