AWS NodeJS App 03 – Pesquisa por produtos

Neste tutorial vamos implementar a funcionalidade de busca de produtos pela caixa de texto que esta no topo da página. Para isso vamos utilizar o método Scan do DynamoDB para recuperar os produtos cujo nome sejam semelhante com a busca que estamos realizando. Para isso vamos precisar de mais uma biblioteca chamada @aws/dynamodb-expressions para realizar a comparação dos valores. Execute o comando a seguir no terminal do Cloud9 para instalar a dependência no projeto.

npm install --s @aws/dynamodb-expressions

Em seguida vamos modificar o código do arquivo index2.hbs para que o campo de consulta direcione a requisição para o controlador de rotas do backend utilizando o método POST. Modificamos o tag FORM para incluir o action e o method POST. Colocamos em comentário todo o tag SELECT para simplificar a busca, e alteramos o tag INPUT para incluir o parâmetro name=”search”

	<div class="col-lg-6 col-sm-8">
			<form action="/" method="POST" class="search-wrap">
				<div class="input-group w-100">
				    <input type="text" name="search" class="form-control" style="width:55%;" placeholder="Search">
				    <!--<select class="custom-select"  name="category_name">
							<option value="">All type</option><option value="codex">Special</option>
							<option value="comments">Only best</option>
							<option value="content">Latest</option>
					</select>-->
				    <div class="input-group-append">
				      <button class="btn btn-primary" type="submit">
				        <i class="fa fa-search"></i>
				      </button>
				    </div>
			    </div>
			</form> <!-- search-wrap .end// -->
	</div> <!-- col.// -->

Então vamos modificar nossa classe ProductService para criar um novo método chamado getAllBySearch. Observe que a biblioteca expressions foi utilizada para carregar a function contains. Em seguida o novo método de busca foi implementado, esse método recebe o parâmetro de busca e chama a função scan passando a class Product e um objeto anônimo contendo o filtro de busca. Uma vez retornado o resultado ele é carregado de forma assíncrona para um vetor list e retornado.

var {
  DataMapper, DynamoDbSchema, DynamoDbTable
} = require('@aws/dynamodb-data-mapper');
var ConditionExpression = require('@aws/dynamodb-expressions');
var {contains} = require('@aws/dynamodb-expressions');
var DynamoDB = require('aws-sdk/clients/dynamodb');

const client = new DynamoDB({region: 'us-east-2'});
const mapper = new DataMapper({client});
const Product = require("../models/product");

class ProductService{
    async getAllBySearch(search){
        var list = [];
        var result = await mapper.scan(Product,{limit:5, filter: {
                                                ...contains(search),
                                                subject: 'name'
                                            }});
        for await (const item of result) {
            list.push(item);
        }
        return list;
   }
   async getAll(){
        var list = [];

        var result = await mapper.scan(Product,{limit:5});
        for await (const item of result) {
            list.push(item);
        }
        return list;

   } 
   
}
module.exports = ProductService;

Agora podemos alterar nossa classe IndexController, para criar o método search que será a ação executada toda vez que a rota “/” receber uma requisição utilizando o método POST. Esse método verifica se no body da requisição foi passado o parâmetro search, caso não tenha sido passado ele executa o método de busca do serviço para retornar todos os itens, e caso contrário, executa o método getAllBySearch.

var ProductService = require("../services/productservice");
var productService = new ProductService();

class IndexController{
    async index(req,res,next){
        var listProduct  = await productService.getAll();
        //console.log(JSON.stringify(listProduct, null, 4));
        res.render('index2', { listProduct: listProduct });
    }
    
    async search(req,res,next){
        var search = req.body.search;
        var listProduct  = null;
        if(search ===""){
            listProduct  = await productService.getAll();
        }else{
            listProduct  = await productService.getAllBySearch(search);
        }
        res.render('index2', { listProduct: listProduct });
    }
}
module.exports = IndexController;

Por fim vamos alterar o arquivo index.js para incluir a nova rota que será delegada para o método search do IndexController.

var express = require('express');
var router = express.Router();

var IndexController = require("../controller/indexcontroller");
var indexController = new IndexController();

/* GET home page. */
router.get('/', function(req, res, next) {
    indexController.index(req,res,next);
});
router.post('/', function(req, res, next) {
    indexController.search(req,res,next);
});

module.exports = router;

Execute novamente a aplicação utilizando o comando nodemon, e verifique se o campo de busca retorna a lista de produtos de acordo com os valores.