Describe the bug
In DownloadBloc, I have a httpRepository to handle download file, and of course with callback of how many percentage. For example:
} else if (event is EventDownloadStart) {
String fileSavePath = await httpRepository.downloadFile(
..
progressCallback: ((int count, int total) {
double percent = count * 100 / total;
yield StateDownloadProgress(progress: percent);
}),
...
);
However I notice cannot invoke yield here because of compiler error: The built-in identifier 'yield' can't be used as a type.
Expected behavior
I would like to know how can I send back percentage data to main UI.
Additional context
It seems there is similar issue (#171 - Function callbacks in Bloc). According to your suggestion in that issue, should I create additional DownloadProgressLoc to dispatch progress?
Hi @anticafe I think you need to mark your callback function as async* in order to be able to yield. Let me know if that helps 馃憤
Closing this for now but feel free to comment with any other questions/comments and I can reopen this/continue the conversation. 馃憤
Unfortunately if I mark callback function as async* then no log as well as yield at all.
Otherwise if I remove async* then there is log but no yield.
My code is:
Stream<StateViewFile> mapEventToState(
...
} else if (event is EventDownloadStart) {
String fileSavePath = await httpRepository.downloadFile(
..
progressCallback: onProgressCallback,
...
);
...
onProgressCallback(int count, int total) async* {
double percent = count * 100 / total;
print('fileRepository.downloadFile $progress% ($percent%)');
yield StateDownloadProgress(progress: progress);
}
FYI, I use Dio for download request, and progressCallback come from that lib too.
Can you please put together a simple sample app that has the same problem? It鈥檇 be much easier for me to help if you can share a sample that I can run locally. Thanks!
@felangel Here you are: https://drive.google.com/open?id=1uaZuKrHTD9KE7EzmYR8BBh7Yi0OV801x
@anticafe thanks! You can see the working version here. 馃憤
@felangel It looks so good. Now it's possible to dispatch download progress although requires more code than just Bloc. Thank you so much for spending time to help me resolve this hard problem. 馃
@anticafe no problem! Glad I was able to help 馃槃
I have the same issue (using DIO and progress callback).
The link with the answer is broken :(
I try to reinject Event in bloc when progress is updated.
BUT the UserAvatarPictureUploadProgressEvent are only fired in the bloc when the updateUserPicture await function is completed
@override
Stream<UserAvatarUpdatePictureState> mapEventToState(
UserAvatarUpdatePictureEvent event) async* {
if (event is UserAvatarPictureUploadProgressEvent) {
yield UserAvatarPictureUploadProgress(
send: event.send, total: event.total);
}
if (event is UserAvatarUpdatePicture) {
try {
final updateResponse = await Api().updateUserPicture(
bytes: event.imageBytes,
file: event.file,
progress: (send, total) async {
add(UserAvatarPictureUploadProgressEvent(
send: send, total: total));
});
@felangel It looks so good. Now it's possible to dispatch download progress although requires more code than just Bloc. Thank you so much for spending time to help me resolve this hard problem.
Can you please post the answer ? (link is broken)
I'm having the same problem. @felangel could you provide a solution that is available to the public? The drive link is broken.
Sure, I'll create a recipe for it 馃憤 (will try to get to it later today/tomorrow)
I'm waiting for it.
@stay-safe sorry been swamped but will try to get to it tomorrow!
Still waiting
Sorry for the delay! You can check out the gist. I'll add it to the website recipes with written explanations shortly 馃憤
Most helpful comment
@felangel It looks so good. Now it's possible to dispatch download progress although requires more code than just Bloc. Thank you so much for spending time to help me resolve this hard problem. 馃