0

I want to use this method, but instead of returning Future<void>, I want to return a value from it. This value is either a final list of bytes or an error (if error happens anytime).

I don't know how to that, since you can't return a value from onDone or onError. If I use await for instead of listen, the errors behave strangely. How to do that?

Future<void> _downloadImage() async {
    _response = await http.Client()
        .send(http.Request('GET', Uri.parse('https://upload.wikimedia.org/wikipedia/commons/f/ff/Pizigani_1367_Chart_10MB.jpg')));
    _total = _response.contentLength ?? 0;

    _response.stream.listen((value) {
      setState(() {
        _bytes.addAll(value);
        _received += value.length;
      });
    }).onDone(() async {
      final file = File('${(await getApplicationDocumentsDirectory()).path}/image.png');
      await file.writeAsBytes(_bytes);
      setState(() {
        _image = file;
      });
    });
  }
May
  • 93
  • 7
  • all you need is simple `_response.stream.pipe(fileSink)` - that's all – pskink Dec 02 '22 at 20:54
  • Hello:) thank you! I must be doing something wrong, since something isn't working. I use Dio now and it's OK, but I'm still curious as to how to make this work. Can you modify the code above perhaps so that it will catch any possible errors or return this file bytes? – May Dec 02 '22 at 21:02
  • 1
    you don't need those bytes, what if your file to download has some hundreds of MB? all you need is `Stream.pipe` method - the docs say: "Pipes the events of this stream into streamConsumer. All events of this stream are added to streamConsumer using StreamConsumer.addStream. The streamConsumer is closed when this stream has been successfully added to it - when the future returned by addStream completes without an error." – pskink Dec 03 '22 at 05:44
  • Ok, thank you. I really don't need the bytes, but I need to return success or error message and use it in a different place. This is how the app is structured. How do I return an error at least? I'm still confused, don't know what is stream consumer, sink File etc. – May Dec 03 '22 at 08:35
  • `class Download { Download(this.stream, this.sink, this.size, [this.callback]); final Stream> stream; final IOSink sink; final int size; Function(double)? callback; int cnt = 0; Future start() => stream .map(_mapper) .pipe(sink); _mapper(List bytes) { cnt += bytes.length; callback?.call(cnt / size); return bytes; } }` - here `start()` method returns a `Future` - you need to `await` it - when everything is ok it returns without throwing any error, if there is something wrong it throws so you nees `try ... catch ...` – pskink Dec 03 '22 at 09:36

0 Answers0