RxDart - Handling Multiple Responses for the Same Event in a Single Bloc
요구 상황 :
StreamSubscription<List<DocumentState>>? _uploadSubscription;
late final documentBloc = context.read<DocumentBloc>();
void _submitDocuments() {
// 1. 업로드가 필요한 문서를 가져옴
final uploadingDocuments = requiredDocumentsCubit.state.documents.uploadingTypeDocuments();
// 업로드할 문서가 없으면 종료
if (uploadingDocuments.isEmpty) return;
// 2. 각 문서에 대한 업로드 이벤트 전송 및 상태 스트림 수집
final uploadStateStreams = uploadingDocuments.map((document) {
// 각 문서별 업로드 이벤트 전송 (documentBloc에 이벤트 추가)
documentBloc.add(
UpdateDocument(
documentType: document.documentType,
photoData: document.photoData,
),
);
// 각 문서의 업로드 결과(성공/실패) 중 첫 번째 방출 값을 Stream으로 변환, 이를 리스트로 수집
return documentBloc.stream
.where((state) => state is UploadDocumentSuccess || state is UploadDocumentFailure)
.first
.asStream();
}).toList();
// 3. 모든 업로드가 끝난 후 로직 수행
_uploadSubscription = Rx.forkJoin(uploadStateStreams, (List<DocumentState> states) => states).listen(
(states) {
if (!mounted) return;
// 모든 업로드가 성공했는지 확인
final isAllUploadSuccess = states.every((state) => state is UploadDocumentSuccess);
// 최종 상태를 가져옴 (실패 시 실패 상태, 성공 시 첫 성공 상태)
final finalState = isAllUploadSuccess
? states.firstWhere((state) => state is UploadDocumentSuccess)
: states.firstWhere((state) => state is UploadDocumentFailure);
// UI 업데이트 및 후속 처리
_onDocumentBlocListener(context: context, state: finalState);
// 모든 업로드 성공 시 승인 이벤트 전송
if (isAllUploadSuccess) {
approvalRequiredDocumentsBloc.add(const DoApprovalModifyRequiredDocuments());
}
},
onDone: () => _uploadSubscription?.cancel(),
onError: (error) {},
);
}
Last updated