upload method

  1. @override
Future<Either<Failure, Response>> upload({
  1. required String endpoint,
  2. Map<String, dynamic> fields = const {},
  3. List<UploadFile> files = const [],
  4. HttpMethod method = HttpMethod.post,
  5. Map<String, dynamic>? params,
  6. Duration? receiveTimeout,
  7. Duration? sendTimeout,
  8. Map<String, String>? headers,
  9. ProgressCallback? onSendProgress,
  10. CancelToken? cancelToken,
  11. bool showLoader = true,
})
override

Uploads files as a multipart request, alongside any ordinary form fields.

Saves hand-building FormData and gets the platform detail right: UploadFile.fromPath on mobile and desktop, UploadFile.fromBytes on web, where a picked file has no filesystem path.

final result = await _api.upload(
  endpoint: '/profile/avatar',
  fields: {'userId': '42'},
  files: [UploadFile.fromPath(field: 'avatar', path: picked.path)],
  onSendProgress: (sent, total) => progress.value = sent / total,
);

Defaults to POST; pass method for an API that expects PUT or PATCH.

A timeout is never retried, since the server may already have stored the file. A 429 or 503 is, because the server said it did not process the request — as is a replay after a 401 refresh, which matters for an upload long enough to outlive its token. In both cases the multipart body is rebuilt first: it is a stream, and sending the consumed one would throw.

Implementation

@override
Future<Either<Failure, Response>> upload({
  required String endpoint,
  Map<String, dynamic> fields = const {},
  List<UploadFile> files = const [],
  HttpMethod method = HttpMethod.post,
  Map<String, dynamic>? params,
  Duration? receiveTimeout,
  Duration? sendTimeout,
  Map<String, String>? headers,
  ProgressCallback? onSendProgress,
  CancelToken? cancelToken,
  bool showLoader = true,
}) {
  return _respond(method, endpoint,
      data: fields, params: params, headers: headers, files: files);
}