Search buenodc

Atualizando e excluindo um produto

Até agora fizemos uma aplicação que exibe uma lista de produtos e mostra os detalhes de cada um deles. Agora vamos adicionar a funcionalidade de atualizar um produto.

Para isso, vamos adicionar um link na página de detalhes de um produto que leva para uma página de formulário para atualizar o produto. Essa página vai ter um formulário com os dados do produto e um botão para enviar o formulário.

Nessa etapa vamos juntar os conhecimentos aprendidos anteriormente para conseguir fazer essa funcionalidade. Vamos começar criando uma nova rota para a página de formulário de atualização de produto usando a visão list que vai ser bem similar a que usamos para detalhar o produto, mudando apenas o nome da página.

<td>
    <a th:href="@{/products/show(id = ${product.id})}">Show</a>
    <a th:href="@{/products/edit(id = ${product.id})}">Edit</a>
</td>

Agora precisamos criar a rota para essa página que deve receber o parâmetro id que vai ser o id do produto que queremos atualizar. Vamos criar um novo método no nosso controller para essa rota.

    @GetMapping("/products/edit")
    public String edit(Model model, @RequestParam("id") String id){
        Product product = findProductById(id);
        model.addAttribute("product", product);
        return "edit";
    }

Perceba que o método é bem similar ao método show que criamos anteriormente, com a mesma lógica de recuperar o id passado via URL, fazer a busca do produto na lista de produtos, adicionar esse produto no container da visão e retornar o nome da visão, que nesse caso chamamos de edit pois é uma nova página.

Vamos criar essa nova página edit.html na pasta src/main/resources/templates. A ideia é que essa página seja bem similar a página create que criamos anteriormente, com um formulário para atualizar o produto, só que dessa vez um formulário populado com os dados daquele produto em questão.

<form method="post" th:action="@{/products/update}">
    
    <input type="hidden" th:field="${product.id}" id="id">

    <label for="name">Nome</label>
    <input type="text" th:field="${product.name}" id="name">

    <label for="description">Descrição</label>
    <input type="text" th:field="${product.description}" id="description">

    <label for="price">Preço</label>
    <input type="text" th:field="${product.price}" id="price">

    <button type="submit">Salvar</button>
</form>

Temos 2 modificações importantes nesse formulário em comparação ao formulário de novo produto. A primeira é que adicionamos um campo hidden para o id do produto. Esse campo é necessário para que o Spring consiga identificar qual produto estamos atualizando. A segunda modificação é a rota, que em vez de apontar para store agora aponta para update. Ou seja, em vez de apenas cadastrar esse novo produto, vamos atualizar um produto já existente.

A última parte do nosso trabalho é criar a rota para atualizar o produto. Vamos criar um novo método no nosso controller para essa rota.

    @PostMapping("/products/update")
    public String update(Product product){
        Product productToUpdate = findProductById(product.getId());
        productToUpdate.setName(product.getName());
        productToUpdate.setDescription(product.getDescription());
        productToUpdate.setPrice(product.getPrice());
        return "redirect:/products";
    }

Nessa rota temos mapeado o método Post pois os dados estão vindo diretamente do formulário e não via URL. Além disso, temos um parâmetro Product que é o produto que estamos atualizando. Esse parâmetro é preenchido automaticamente pelo Spring com os dados do formulário, pois os campos do formulário tem o mesmo nome dos atributos da classe Product.

A partir desses dados, fazemos a busca do produto na lista de produtos e atualizamos os dados desse produto com os dados que vieram do formulário. Por fim, retornamos um redirecionamento para a página de listagem de produtos. Teste no navegador e verá que agora é possível atualizar um produto.

Excluindo um produto

Agora é a vez de excluir um produto da lista. Para isso precisamos de um link que aponte para uma rota de exclusão e do método que vai remover o produto.

Comece adicionando o link de exclusão ao lado dos links de detalhes e edição. Ele é bem parecido com o link de edição, mudando apenas a rota:

<td>
    <a th:href="@{/products/show(id = ${product.id})}">Show</a> |
    <a th:href="@{/products/edit(id = ${product.id})}">Edit</a> |
    <a th:href="@{/products/delete(id = ${product.id})}">Delete</a>
</td>

Agora crie a rota que recebe o parâmetro id, procura o produto na lista e o remove:

    @GetMapping("/products/delete")
    public String delete(@RequestParam("id") String id){
        Product product = findProductById(id);
        products.remove(product);
        return "redirect:/products";
    }

Abra o navegador e teste a exclusão de um produto.