‫Jonas: Nesta segunda parte do upload das imagens da
‫turnê, vamos processar todas elas.
‫Mas antes de começarmos
‫a fazer isso, há algo que
‫preciso consertar no controlador do usuário.
‫E então nesse resizeUserPhoto, e é
‫aí que precisamos
‫aguardar toda essa operação aqui, certo?
‫Então, tudo isso aqui vai realmente retornar uma promessa, e
‫isso faz sentido, certo,
‫porque todas essas operações aqui levam algum tempo e,
‫é claro, acontecem em segundo plano.
‫Portanto, eles são códigos assíncronos
‫e, portanto, obviamente, não devem bloquear o loop de eventos.
‫Agora, o problema aqui é
‫que agora estamos chamando esta próxima
‫função aqui, então o próximo middleware, sem realmente
‫esperar que essas operações aqui terminem.
‫E isso não é uma boa ideia.
‫Então, vamos simplesmente usar
‫await aqui e, claro, assíncrono, e todas essas coisas.
‫Então catchAsync aqui.
‫Tudo bem, salve, e isso é muito melhor.
‫E agora vamos fazer algo
‫muito semelhante com as imagens da turnê.
‫E então, na verdade, deixe-me ir em frente e copiar isso.
‫Tudo bem, e
‫embora não vá ser exatamente igual, é bom já ter aqui.
‫Portanto, esta também será uma função assíncrona.
‫Tudo bem, agora como antes, caso não
‫haja nenhuma imagem carregada, então
‫queremos ir direto para o próximo middleware.
‫Portanto, se não houver pedido. arquivos e, na verdade, vou
‫dar um passo adiante, exigindo que
‫haja tanto a capa da imagem quanto
‫as imagens.
‫Basicamente, queremos passar para o próximo middleware, caso
‫não haja solicitação. arquivos. imageCover
‫ou nenhuma solicitação. arquivos. imagens.
‫Então, nesse caso, a seguir.
‫Ok, e agora vamos começar processando a imagem
‫da capa e, em seguida, todas as outras imagens em um
‫loop, basicamente.
‫Portanto, outras imagens.
‫Agora, de onde realmente tiramos a imagem da capa?
‫Bem, lembre-se de como eu disse que está a pedido. arquivos?
‫Não arquivo mais, e então. coverImage ou,
‫na verdade, imageCover.
‫E então lembra como era um array?
‫Então, vamos dar uma olhada nisso mais uma vez.
‫Certo, então tudo isso é pedido. arquivos e,
‫a partir daí, pegamos imageCover, que
‫é um array de um elemento.
‫E agora queremos o elemento número zero, e
‫então. amortecedor.
‫Então, essa coisa de aparência estranha aqui.
‫Então queremos redimensionar para uma proporção de
‫2/3, e a largura será
‫de 2.000 pixels e a altura de 1.333, certo?
‫E então, novamente, essa é uma boa proporção de 3/2,
‫o que é muito comum em imagens.
‫Em seguida, também queremos formatá-lo como JPEG com qualidade de 90% e
‫salvá-lo como um arquivo.
‫Mas desta vez é para imagens /
‫tours, e aqui vamos definir nosso nome de arquivo separadamente.
‫Tudo bem, porque na verdade vamos precisar de novo.
‫Então, imageCoverFilename, e mais
‫uma vez, agora precisamos criar um nome de arquivo exclusivo.
‫Agora é o tour, e vamos colocar novamente o
‫ID do tour aqui, onde antes estava o ID do usuário.
‫E isso está a pedido. params, então lembre-se que
‫este roteiro sempre conterá
‫o ID do passeio, portanto está
‫sob consulta. params. Eu iria.
‫Em seguida, novamente o carimbo de data / hora, Data. agora, digamos que
‫essa é a imagem da capa, ok?
‫E os outros receberão alguns números.
‫E então é claro. JPEG, então vamos usar isso aqui.
‫Então, imageCoverFilename.
‫Ok, e agora como uma última etapa, precisamos
‫tornar possível que nosso
‫gerenciador de tour de atualização
‫pegue o nome do arquivo da capa da imagem para
‫atualizá-lo no documento de tour atual, certo?
‫Portanto, vamos rapidamente dar
‫uma olhada em como o documento é realmente atualizado.
‫E, portanto, estamos usando de
‫forma muito simples essa função de fábrica updateOne.
‫E esse irá simplesmente atualizar todos os dados que
‫estão no corpo para o novo documento.
‫Então, só para provar isso aqui.
‫Portanto, updateOne leva em conta toda a solicitação. corpo, ok?
‫E agora o segredo é colocar esse nome de arquivo
‫de capa de imagem a pedido. corpo, tudo bem?
‫Então, peça. corpo. imagem de capa.
‫Ah, e de novo, é chamado imageCover
‫em vez disso, deve ser igual a imageCoverFilename, ok, faz sentido?
‫E, claro, é chamado de imageCover
‫porque esse é o nome que temos em nossa definição de esquema.
‫E então, quando estiver fazendo a
‫atualização, ele irá combinar este campo no corpo com
‫o campo em nosso banco de dados.
‫E, na verdade, podemos refatorar isso
‫um pouco porque realmente não precisamos desse nome de variável aqui.
‫Portanto, poderíamos simplesmente colocar esse nome de arquivo aqui, bem no corpo.
‫Portanto, coloque-o aqui e, em seguida, use-o aqui imediatamente.
‫Portanto, não precisamos dessa linha de código.
‫Ótimo, e agora antes de passar para as outras imagens, vamos
‫realmente testá-lo com o que já temos
‫neste momento.
‫Então, vamos nos livrar deste console. log, e
‫quando agora fizermos a solicitação,
‫nossa imagem de capa já deve ter
‫sido carregada e colocada no documento do tour, ok?
‫Então, essas outras três imagens aqui é claro que não,
‫mas pelo menos a
‫capa da imagem deve estar funcionando
‫agora, pelo menos se fizemos tudo certo.
‫Então, vamos ver se ele está em algum lugar
‫aqui e as imagens ainda estão vazias, obviamente.
‫Mas agora estou procurando a imagem da capa, então onde está?
‫E aqui está, então imageCover, e isso
‫se parece muito com o nome do
‫arquivo que acabamos de especificar.
‫E vamos tentar recarregar nossa página de todos os passeios aqui, e talvez
‫nosso novo passeio já esteja aqui.
‫Ah, aqui vamos nós, então esse é o novo passeio de mountain bike.
‫E esta aqui é de fato a imagem que acabamos de enviar.
‫Tão bonita.
‫Agora, se tentarmos abrir
‫esta página, então as outras imagens não estão aqui, certo?
‫Então, eles não estão em lugar
‫nenhum, então é claro que vamos fazer a seguir.
‫Tudo bem.
‫Portanto, lembre-se de que nossas
‫imagens aqui também são uma matriz,
‫que contém todos esses novos uploads de arquivo.
‫E agora vamos usar um loop
‫para processar cada um deles em uma iteração.
‫Então, peça. arquivos. imagens. para cada.
‫E então nossa função
‫de retorno de chamada na qual obtemos acesso ao arquivo atual.
‫Tudo bem, agora aqui realmente precisamos criar o
‫nome do arquivo atual e você verá o
‫porquê em um segundo.
‫Então, o nome do arquivo é igual, e então algo muito semelhante a isso.
‫Com a diferença de que agora não é
‫cobertura, mas em vez disso, queremos chamá-los de um, dois e três.
‫E assim, em nossa
‫função de retorno de chamada, também obtemos acesso ao índice atual, certo?
‫Portanto, precisamos do arquivo e I para o índice.
‫E então aqui não é a capa, mas o índice mais um.
‫Então mais um, e isso só
‫porque esse índice é baseado em zero, certo?
‫Em seguida, vem a própria etapa de processamento,
‫que também é muito semelhante a esta.
‫E agora, é claro, precisamos marcar isso como assíncrono também.
‫Certo, e aqui embaixo agora é o nome do arquivo.
‫Ok, agora por que realmente precisamos desse nome de arquivo?
‫Bem, precisamos disso porque agora precisamos enviar esse nome
‫de arquivo para solicitação. corpo. imagens, e essa é exatamente a mesma lógica que
‫tínhamos aqui antes, a pedido. corpo. imageCover.
‫Portanto, lembre-se de que, em
‫nossa coleção, solicite. corpo. as imagens são, na verdade, uma matriz.
‫E agora precisamos criar esse array e iniciá-lo
‫como um array vazio.
‫Portanto, peça. corpo. images
‫como um array vazio e, em cada iteração,
‫enviaremos o nome do arquivo atual
‫para esse array de imagens.
‫Então, peça. corpo. imagens. push,
‫o nome do arquivo, certo?
‫E com isso estamos quase terminando.
‫Há apenas um pequeno problema, que
‫é o fato de que
‫na verdade não estamos usando async await corretamente aqui neste
‫caso, portanto, neste loop.
‫E isso porque este async await
‫aqui está apenas dentro dessa função de retorno
‫de chamada do loop foreach.
‫E isso não impedirá que
‫o código se mova para a direita ao lado
‫dessa linha, onde chamamos o próximo middleware, certo?
‫Então, novamente, no momento não estamos esperando nada
‫disso aqui, novamente, porque essa espera assíncrona acontece dentro da
‫função de retorno de chamada
‫de um desses métodos de loop.
‫E já nos deparamos com esse tipo de
‫problema antes, mas felizmente há uma solução para
‫isso, porque, como essa é uma função assíncrona
‫aqui, ela retornará uma nova promessa.
‫E se fizermos um
‫mapa, podemos salvar uma série de todas essas promessas.
‫E então, se tivermos um array,
‫podemos usar a promessa. tudo para esperar todos eles.
‫E com isso vamos então realmente esperar
‫até que todo esse código, e neste caso,
‫até que todo esse processamento de imagem
‫seja feito, e só então passar para a próxima
‫linha, que está chamando o
‫próximo middleware para realmente atualizar os documentos do tour.
‫E se não fizéssemos
‫isso nesse caso, realmente
‫não funcionaria, porque sem esse empurrar aqui,
‫o pedido. corpo. as imagens ainda estariam vazias
‫na próxima chamada.
‫Portanto, nenhum desses nomes
‫de imagem seria persistido no documento, certo?
‫Portanto, agora vamos usar a promessa. todos e,
‫na verdade, nem mesmo estou salvando esse array aqui em nenhuma variável, em
‫vez disso, vou usar a promessa. tudo imediatamente sobre
‫isso.
‫Portanto, aguarde a promessa. tudo na
‫matriz retornando disso, ok?
‫Espero que tenha feito sentido.
‫Portanto, agora vamos realmente registrar o corpo aqui no console.
‫Tudo bem, com isso devemos estar prontos para fazer o
‫upload de todas as nossas imagens, certo?
‫Vamos descer aqui e tentar novamente.
‫Tudo bem, então onde está nossa matriz de imagens?
‫Bem, talvez estivesse em algum lugar aqui, ah, aqui está.
‫Então eu perdi isso de alguma forma.
‫E isso parece muito promissor, certo?
‫Então, três belas imagens, vamos
‫agora dar uma olhada aqui em nossa página.
‫Ah, aí estão eles, mas não exatamente corretos, certo?
‫Parece que simplesmente carregamos a imagem
‫da capa três vezes.
‫Então, vamos dar uma olhada no Postman, mas
‫os nomes das imagens estão realmente
‫corretos e, portanto, há algo errado em nosso processamento ali.
‫Vamos dar uma olhada também nas solicitações. corpo, oh, e eu esqueci
‫de realmente colocá-lo aqui.
‫Ok, mas acho que nem é necessário porque acabamos
‫de ver no Postman
‫que os nomes dos arquivos estão corretos.
‫Portanto, não precisamos mais deste.
‫Agora vamos dar uma olhada nos nomes
‫de arquivo que acabamos de enviar, para que estejam em público e em tours.
‫E então aqui estão eles.
‫Portanto, este foi provavelmente o primeiro do último teste.
‫E, como você pode ver, todos eles são, de
‫fato, exatamente a mesma imagem.
‫Portanto, capa, um, dois e três são as mesmas imagens
‫e, portanto, isso não está correto.
‫E posso ver imediatamente qual é o problema.
‫Então, você vê que, na verdade, ainda estamos lendo
‫o pedido. arquivos. imageCover, e
‫não o arquivo da iteração atual deste loop.
‫Ok, então, em vez disso, esse deve ser o arquivo. amortecedor.
‫Tudo bem, então vamos em frente
‫e deletar tudo isso.
‫Tudo bem, e simplesmente tente novamente agora.
‫Então, vamos enviar isso.
‫Os nomes ainda parecem
‫estar corretos, mas agora, quando recarregarmos, vamos ver.
‫Ah, isso parece correto.
‫Lindo lindo.
‫Você vê que as imagens estão todas bem
‫formatadas, até essa que estava, lembre-se,
‫em retrato e nem mesmo
‫paisagem, mas basicamente recortamos isso e ainda está lindo.
‫Ok, então aqui podemos confirmar isso, de
‫modo que está na casa dos 2.000 por 1.333 pixels.
‫Tudo bem, ainda está um pouco para o lado grande aqui,
‫então talvez pudéssemos reduzir a qualidade um pouco mais, mas
‫isso não é muito importante.
‫O que realmente importa aqui
‫é que a lógica que acabamos de aplicar aqui realmente funciona.
‫Então, apenas para recapitular rapidamente o que fizemos nessas duas palestras.
‫Então criamos um upload de multer usando o armazenamento de memória
‫e esse filtro apenas para imagens.
‫Em seguida, criamos o middleware de imagem do
‫tour de upload usando upload. campos, que pega em
‫uma capa de imagem e três imagens, e
‫depois na requisição vai colocar a propriedade de arquivos assim, tá bom?
‫Então, em nosso próximo middleware, redimensionamos essas imagens, primeiro
‫a imagem da
‫capa e, em seguida, as três imagens restantes.
‫E o que é realmente importante observar aqui
‫é como colocamos os nomes dos arquivos de imagem sob solicitação. corpo.
‫E fazemos isso para que no
‫próximo middleware, que é o
‫gerenciador de rota real, ele coloque esses dados
‫no novo documento quando for atualizá-lo, certo?
‫Então, fazemos isso com a capa da imagem,
‫e também fazemos isso com as imagens restantes,
‫empurrando-a para dentro do corpo. imagens, que como
‫sabemos de nosso esquema de
‫passeio, espera uma série de strings.
‫E então, neste caso, nomes de arquivos.
‫Então, sobre essas outras imagens,
‫nós as pedimos. arquivos. imagens, então é um
‫array, e é claro que fazemos um loop através dele usando map.
‫E usamos map para que possamos basicamente
‫salvar as três promessas que são
‫o resultado dessas três funções assíncronas aqui,
‫então podemos esperar todas elas
‫aqui usando Promise. Tudo certo?
‫E só depois disso passamos para
‫o gerenciador de atualização do tour real, certo?
‫E essa parte é muito importante,
‫por isso é importante que apenas
‫passemos para o próximo middleware assim que esta parte aqui
‫estiver realmente concluída.
‫Porque caso contrário, peça. corpo. as imagens ficarão
‫vazias e, claro, os nomes dos nossos arquivos não
‫serão salvos no documento da turnê atual, certo?
‫E isso realmente encerra a
‫parte da imagem ou do upload do arquivo desta seção.
‫Espero que tenha sido divertido,
‫sei que para mim foi muito legal.
‫Eu realmente gosto desse tipo
‫de coisa, o que faz minhas aplicações parecerem do mundo real.
‫De qualquer forma, espero que tenham gostado
‫e nos vemos no próximo.