Doubt with Nested Observables (Angular 8 & Ionic 4)

Asked

Viewed 155 times

2

Good afternoon,

I would like guidance on the Observables.

I’m making an app for learning, where I insert products in a shopping cart, these products in case would be vegetables.

I will try to be brief in explaining the structure of my project to be clear.

My products are in a database (Mongodb) and are as follows:

{imagemUrl: "assets/Agriao.jpg", nome: "Agrião", preco: 2, quantidade: 9, _id: 12}
{imagemUrl: "assets/Rucula.jpg", nome: "Rúcula", preco: 2, quantidade: 15, _id: 31}

When I add a product to the cart, each product goes as an object that way:

{nomeProduto: "Agrião", compraQtd: 1, precoUnitario: 2, _idProduto: [12, 12]}
{nomeProduto: "Agrião&Rúcula", compraQtd: 1, precoUnitario: 2, _idProduto: [12, 31]}

You may wonder why the _idProduct has an array of the Product ID, this is because each package of a given product contains two feet of the same, the purchase in the application is not per quantity of each product and yes per package, these products can be of one type only (Watercress) or can be mixed (watercress & arugula), so I put in an array the ID’s of the respective products that are being purchased, because it is through this ID that I will later debit the amount of his stock in the database.

Now I’ll really explain my difficulty:

Let’s say that I only add the product Watercress in the cart, I will buy a package of the same, remembering that each package contains two feet of the product, therefore, should be charged two watercress of the stock of its total quantity, that at the moment it has the amount of 9. In my cart, at the end of the purchase there is the following method:

this.itensDoCarrinho.forEach(pedidoCompra => { //Aqui eu faço um forEach para cada produto que está no meu carrinho.
        console.log("PedidoCompraModel", pedidoCompra);
        pedidoCompra._idProduto.forEach(idProduto => { //Aqui eu faço um forEach para cada ID que está dentro do meu pedidoCompra.
          this.produtoService.getProduto(idProduto) //Aqui eu faço uma requisição para o meu banco através do HttpClient para me trazer informações do produto que estou querendo debitar do estoque.
            .subscribe(produtoDados => {
              console.log("Produto Dados do GetProduto", produtoDados);
              this.produtoService.updateQtdProduto(produtoDados._id, { "quantidade": produtoDados.quantidade - pedidoCompra.compraQtd }) //Aqui é onde eu faço o debito da quantidade comprada relativa ao ID informado e dou um patch atualizando o banco de dados.
                .subscribe(produtoDadosAtualizado => {
                  console.log("Produto Dados do UpdateQtdProduto", produtoDadosAtualizado);
                });
            });
        });
      });

However, what happens is that it only debits ONE QUANTITY of the product in question, and not two quantities, as I would like it to be. I have the impression that this has something to do with the asymchronism of the Observables.

I’ll put down a console.log photo of the above operation so you can understand more clearly what happened.

Imagem do Console.log do exemplo citado

Would anyone know what this is all about? What I could do to have the product quantity correctly charged according to the ID’s that are reported on Pedidocompramodel?

I’m sorry if I couldn’t be very clear in my explanation, any other information, please just ask me.

Thank you for your time!

1 answer

1


Really the problem is because the methods are asynchronous.

A possible solution would be as follows:

contaQuantidadeCadaProduto() {
    const produtos: [{ id: number, quantidade: number }] = [];

    this.itensDoCarrinho.map(pedidoCompra => {

        pedidoCompra._idProduto.map(idProduto => {

            // verifica se o produto ja foi adicionado ao array
            let index = produtos.findIndex(p => p.id == idProduto);

            // se o produto for encontrado, incrementa a quantidade, caso contrario adiciona
            if (index !== -1) {
                produtos[index].quantidade++;
            } else {
                produtos.push({id: idProduto, quantidade: 1});
            }
        });
    });

    this.BuscaProdutosEAtualiza(produtos);
}

BuscaProdutosEAtualiza(produtos: [{ id: number, quantidade: number }]) {
    produtos.map(p => {
        this.produtoService.getProduto(p.id)
            .subscribe(produtoDados => {
                this.atualizaQuantidadeProduto(produtoDados, p.quantidade);
            });
    });
}

atualizaQuantidadeProduto(produtoDados, compraQuantidade) {
    this.produtoService.updateQtdProduto(produtoDados._id, { "quantidade": produtoDados.quantidade - compraQuantidade })
    .subscribe(produtoDadosAtualizado => {
        // produto atualizado
    });
}

This way we isolate the functions and quantity upgrades will be done once for each product, solving the problem of many asynchronous requests.

Any questions about the code can be commented here.

  • Man, what a show! I’m sure to learn a lot from now on! Thank you so much for the class and your time! !

  • That’s it! Good luck and good education :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.