I have events that do long synchronisations in the background and they have to update loading status, but at the same time I have to fire other events, unfortunately the bloc's event channel gets blocked, preventing me from firing other events. Can I solve this problem without creating another bloc instance?
Here's my code:
@override
Stream<MailState> mapEventToState(
MailEvent event,
) async* {
if (event is FetchFolders) yield* _fetchFolders(event);
if (event is RefreshFolders) yield* _refreshFolders(event);
if (event is SelectFolder) yield* _selectFolder(event);
if (event is CheckFoldersUpdateByTimer) yield* _checkFoldersUpdateByTimer(event);
if (event is RefreshMessages) yield* _refreshMessages(event);
}
Stream<MailState> _fetchFolders(FetchFolders event) async* {
yield FoldersLoading();
try {
final List<Folder> folders = await _methods.getFolders();
if (folders.isNotEmpty) {
_selectedFolder = folders[0];
yield FoldersLoaded(folders, _selectedFolder);
yield SubscribedToMessages(
_methods.subscribeToMessages(_selectedFolder));
final List<Folder> foldersWithInfo = await _methods.updateFoldersHash(
_selectedFolder,
);
yield FoldersLoaded(foldersWithInfo, _selectedFolder);
yield MessagesSyncing();
// very long running process, up to 40 sec
await _methods.syncFolders(
localId: _selectedFolder.localId, syncSystemFolders: true);
yield MessagesSynced();
} else {
yield FoldersEmpty();
}
} catch (err) {
yield MailError(err.toString());
}
}
md5-b86f2b251316869cdcb71bac7bc3dbe7
Stream<MailState> _selectFolder(SelectFolder event) async* {
try {
final List<Folder> folders = await _methods.getFolders();
_selectedFolder = event.folder;
yield FoldersLoaded(folders, _selectedFolder);
yield SubscribedToMessages(_methods.subscribeToMessages(_selectedFolder));
} catch (err) {
yield MailError(err.toString());
}
}
Hi @VadimOsovsky 馃憢
Thanks for opening an issue!
In your case, I would recommend having events to initiate the long-running processes and then add new events when the processes have completed. This will allow your bloc to process multiple long-running requests in the background and handle their results independently without blocking the event loop.
_methods.syncFolders(
localId: _selectedFolder.localId, syncSystemFolders: true
).then((results) => add(MessagesSynced(results)));
Let me know if that helps 馃憤
@felangel That works perfectly! Thank you for the lightning fast response, the awesome library and for help. You're a great person!
Most helpful comment
@felangel That works perfectly! Thank you for the lightning fast response, the awesome library and for help. You're a great person!