Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obtendo o status de progresso do envio de dados com Axios #6

Open
andreviapiana opened this issue Feb 13, 2023 · 1 comment
Open

Obtendo o status de progresso do envio de dados com Axios #6

andreviapiana opened this issue Feb 13, 2023 · 1 comment

Comments

@andreviapiana
Copy link
Owner

andreviapiana commented Feb 13, 2023

Vamos mostrar na prática como obter o progresso de cada requisição HTTP sendo feita através do método POST, do front end para o back end utilizando o Axios.

 

Caso de uso

 

Imagine que você tem um app front end que faz upload de arquivos para um servidor. Você quer acompanhar e mostrar ao usuário o progresso do envio desses arquivos.
Isso é possível e fácil de implementar utilizando o Axios.

 

Vamos como codar essa funcionalidade.

 

Mensurando o Progresso de Upload na Prática

 

Sintaxe básica:

 

	   // Utilizando axios
	   import axios from axios;

	   // Criando um FormData que armazena a imagem (arquivo)
	   const data = new FormData();
	   data.append("file", file, filename);
  
	   // Fazendo a requisição para o servidor com método POST
	   // Enviando o arquivo que está na variável data
	   // Passando um objeto de configuração que possui um método onUploadProgress
      axios
        .post("https://my.server.com/posts", data, {
          onUploadProgress: (event) => {
            let progress: number = Math.round(
              (event.loaded * 100) / event.total
            );

            console.log(
              `A imagem ${filename} está ${progress}% carregada... `
            );  
          },
        })
        .then((response) => {
          console.log(
            `A imagem ${filename} já foi enviada para o servidor!`
          );    
        })
        .catch((err) => {
          console.error(
            `Houve um problema ao realizar o upload da imagem ${filename} no servidor AWS`
          );
          console.log(err); 
        });

 

Basicamente é realizado uma requisição do tipo POST utilizando o Axios, passando a variável data, com o arquivo. Passamos também um objeto com a configuração da requisição. Nele contém o método onUploadProgress que recebe um event, esse event contém as propriedades loaded e total.

 

loaded é o quanto já foi carregado e total armazena o tamanho total do arquivo.

 

Então é feito um cálculo de regra de três para definir a percentagem que já foi carregada no servidor. A variável progress armazena esses valores conforme a função onUploadProgress é executada automaticamente.

 

Como estamos lidando com uma Promises, no final da execução o método Then é executado e conseguimos informar que o arquivo já foi enviado.

 

Se houver algum erro, o método Catch é executado, assim podemos imprimir no log o erro.

 

Até aqui entendemos a lógica de como funciona o progresso do envio de arquivos.

 

No código abaixo vamos explorar um pouco mais sobre o assunto, mostrando um trecho de código que foi utilizado no exemplo de caso de uso.

 

import api from "../services/api";

export interface IFile {
  id: string;
  name: string;
  readableSize: string;
  uploaded?: boolean;
  preview: string;
  file: File | null;
  progress?: number;
  error?: boolean;
  url: string;
}

const [uploadedFiles, setUploadedFiles] = useState<IFile[]>([]);

const updateFile = useCallback((id, data) => {
    setUploadedFiles((state) =>
      state.map((file) => (file.id === id ? { ...file, ...data } : file))
    );
  }, []);

const processUpload = useCallback(
    (uploadedFile: IFile) => {
      const data = new FormData();
      if (uploadedFile.file) {
        data.append("file", uploadedFile.file, uploadedFile.name);
      }

      api
        .post("posts", data, {
          onUploadProgress: (progressEvent) => {
            let progress: number = Math.round(
              (progressEvent.loaded * 100) / progressEvent.total
            );

            console.log(
              `A imagem ${uploadedFile.name} está ${progress}% carregada... `
            );

            updateFile(uploadedFile.id, { progress });
          },
        })
        .then((response) => {
          console.log(
            `A imagem ${uploadedFile.name} já foi enviada para o servidor!`
          );

          updateFile(uploadedFile.id, {
            uploaded: true,
            id: response.data._id,
            url: response.data.url,
          });
        })
        .catch((err) => {
          console.error(
            `Houve um problema ao fazer upload da imagem ${uploadedFile.name} no servidor AWS`
          );
          console.log(err);

          updateFile(uploadedFile.id, {
            error: true,
          });
        });
    },
    [updateFile]
  );

 

Nesse código, o evento de onUploadedFile é executado seguindo a mesma lógica que explicamos anteriormente, o progresso será calculado e a função updateFile é chamada a cada update do evento, recebendo o id do arquivo enviado ao servidor e o progresso.

 

A função updateFile irá alterar o estado do arquivo em questão, passando o valor atual do progresso que irá refletir na tela com um Loading de progresso usando a lib react-circular-progressbar. Conforme vimos no vídeo do caso de uso acima.

 

Quando é finalizado o upload do arquivo, o método then é executado e invoca a função updateFile, passando o id fake do arquivo e um objeto que tem o id que o servidor gerou e a URL do arquivo que já foi salva no S3 da AWS.

 

Na tela vai aparecer um link excluir e um ícone representará que o arquivo foi enviado com sucesso!

 

Algum erro pode acontecer na execução, o servidor não permite arquivos maiores que 2 MB.

 

Se o usuário enviar um arquivo maior que o limite estabelecido no servidor, o método catch será executado. Então iremos alterar o estado do uploadedFile com um error: true que irá alterar o ícone no front end, indicando que o arquivo que está no preview não foi enviado por algum motivo — poderíamos colocar um tooltip para mostrar o log do erro no componente ;)

 

E temos aqui o resultado esperado:
image
Imagem sendo enviados ao servidor, um deu erro, três estão sendo enviados e quatro foram enviados com sucesso! Nessa imagem podemos observar o progresso de cada envio 🚀

 

Conclusão

 

Objetivo foi mostrar essa funcionalidade bacana do Axios de ouvir o evento de envio de arquivos e mostrar a quantidade em percentual do processamento do envio, com isso podemos mostrar um loading bem legal.

 

Conseguimos melhorar a experiência do usuário mostrando o progresso do envio arquivo.

 

O objetivo não foi mostrar o fluxo completo do front end, isso vai ficar para um próximo post.

 

Links

 

@andreviapiana
Copy link
Owner Author

Texto extraído diretamente do Blog da Rocketseat.
https://blog.rocketseat.com.br/obtendo-o-status-de-progresso-do-envio-de-dados-com-axios/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant