Update:
A day after posting this I realized that this is not actually measuring the upload progress, but only the progress of reading the bytes from the local JSON payload, which is almost instantaneous. If/when I figure out how to actually measure the upload progress, I'll update this answer.
Original Answer:
This works for me, without using Multipart:
import 'dart:convert';
import 'package:http/http.dart' as http;
// ...
final jsonPayload = {'base64File': 'abc123', 'something': 'else'};
// We are using a StreamedRequest so we can track the upload progress
final streamedRequest = http.StreamedRequest("POST", apiUri);
streamedRequest.headers['content-type'] = 'application/json';
// Length transferred (to calculate upload progress)
var transferredLength = 0;
// Upload progress (from 0.0 to 1.0)
var uploadProgress = 0.0;
// The stringified JSON payload
var stringEncodedPayload = jsonEncode(jsonPayload);
// Total length (to calculate upload progress)
var totalLength = stringEncodedPayload.length;
// Create a stream of the payload string
Stream.value(stringEncodedPayload)
// Transform the string-stream to a byte stream (List<int>)
.transform(utf8.encoder)
// Start reading the stream in chunks, submitting them to the streamedRequest for upload
.listen((chunk) {
transferredLength += chunk.length;
uploadProgress = transferredLength / totalLength;
print("Chunk: ${chunk.length}, transferred: $transferredLength, progress: $uploadProgress");
streamedRequest.sink.add(chunk);
}, onDone: () {
print("Done. Total: $totalLength, transferred: $transferredLength, progress: $uploadProgress");
streamedRequest.sink.close();
});
final result = await client.send(streamedRequest).then(http.Response.fromStream);
print("----------->");
print(result.statusCode);
print(result.body);
print("<-----------");
The output:
flutter: Chunk: 1024, transferred: 1024, progress: 0.0008807503580198599
flutter: Chunk: 1024, transferred: 2048, progress: 0.0017615007160397197
flutter: Chunk: 1024, transferred: 3072, progress: 0.0026422510740595796
...
flutter: Chunk: 1024, transferred: 1159168, progress: 0.9970094052784814
flutter: Chunk: 1024, transferred: 1160192, progress: 0.9978901556365013
flutter: Chunk: 1024, transferred: 1161216, progress: 0.9987709059945211
flutter: Chunk: 1024, transferred: 1162240, progress: 0.9996516563525409
flutter: Chunk: 405, transferred: 1162645, progress: 1.0
flutter: Done. Total: 1162645, transferred: 1162645, progress: 1.0