Oi Bianca, tudo bem?
É ótimo ver você buscando ajuda para resolver um desafio no seu Front-end relacionado ao upload de arquivos usando o método multipart em Angular. Entendo que essa questão pode ser um obstáculo e estou aqui para fornecer orientações claras e respeitosas para solucioná-la.
O problema que você descreve, onde o Front-end se perde ao enviar mais de 5 arquivos usando o método multipart, é relativamente comum em sistemas que lidam com uploads de arquivos fragmentados. Pode ocorrer por diversas razões, mas com a abordagem certa, é possível resolvê-lo. Vamos explorar algumas soluções possíveis para o seu cenário.
1. Controle de Upload Assíncrono
Uma possível causa do problema que você mencionou é a natureza assíncrona das solicitações de upload. Quando várias solicitações de upload são iniciadas ao mesmo tempo, pode haver interferências, resultando em uploads incorretos. Para resolver isso, você pode controlar o upload de arquivos de forma mais precisa. Uma maneira de fazer isso é usar observables para garantir que as partes de cada arquivo sejam enviadas e completadas na ordem correta.
Aqui está um exemplo de como você pode utilizar o Angular e RxJS para controlar o upload de arquivos de forma assíncrona:
import { HttpClient } from '@angular/common/http';
import { Observable, forkJoin } from 'rxjs';
// ...
uploadFile(file: File): Observable<any> {
const chunkSize = 1 * 1024 * 1024; // 1 MB
const totalChunks = Math.ceil(file.size / chunkSize);
const observables = [];
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
// Enviar o chunk atual
observables.push(this.http.post('sua-url-de-upload', chunk, {
headers: {
'Content-Type': 'application/octet-stream',
'Content-Range': `bytes ${start}-${end - 1}/${file.size}`,
}
}));
}
return forkJoin(observables); // Aguarde até que todos os chunks sejam enviados
}
Essa abordagem permite que você envie os chunks em sequência, garantindo a ordem correta de envio. Certifique-se de que sua API de backend esteja configurada para aceitar e processar essas solicitações parciais.
2. Gerenciamento de Estado
Outra possível solução é implementar um sistema de gerenciamento de estado para rastrear o progresso do upload de cada arquivo. Dessa forma, você pode evitar que os uploads sejam completados antes de todas as partes terem sido enviadas com sucesso. Uma biblioteca popular para gerenciamento de estado em Angular é o NgRx.
Aqui está um exemplo simplificado de como você pode usar o NgRx para gerenciar o estado do upload:
// Estado do upload
interface UploadState {
file: File;
totalChunks: number;
uploadedChunks: number;
}
// Ações para gerenciar o upload
enum UploadActionTypes {
START_UPLOAD = '[Upload] Start Upload',
UPLOAD_CHUNK = '[Upload] Upload Chunk',
COMPLETE_UPLOAD = '[Upload] Complete Upload',
UPLOAD_SUCCESS = '[Upload] Upload Success',
UPLOAD_FAILURE = '[Upload] Upload Failure',
}
// Reducer para gerenciar o estado
const initialState: UploadState[] = [];
const uploadReducer = createReducer(
initialState,
on(UploadActions.startUpload, (state, { file, totalChunks }) => {
return [...state, { file, totalChunks, uploadedChunks: 0 }];
}),
on(UploadActions.uploadChunk, (state, { file }) => {
const upload = state.find((u) => u.file === file);
if (upload) {
upload.uploadedChunks++;
return [...state];
}
return state;
}),
// Continue com outras ações para completar e tratar o upload
);
// ...
// Componente de upload
@Component({
// ...
})
export class UploadComponent {
// ...
// Iniciar o upload de um arquivo
startUpload(file: File) {
const totalChunks = Math.ceil(file.size / chunkSize);
this.store.dispatch(UploadActions.startUpload({ file, totalChunks }));
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * chunkSize;
const end = Math.min(start + chunkSize, file.size);
const chunk = file.slice(start, end);
this.http.post('sua-url-de-upload', chunk).subscribe(
() => {
// Atualizar o estado do upload
this.store.dispatch(UploadActions.uploadChunk({ file }));
},
(error) => {
// Lidar com erros de upload
this.store.dispatch(UploadActions.uploadFailure({ file, error }));
}
);
}
}
}
Ao utilizar o NgRx, você pode manter o controle do progresso de cada upload e evitar completar o upload antes que todas as partes tenham sido enviadas com sucesso.
Um abraço e bons estudos.