2

I am trying to upload image using Flutter's http plugin.

Following is my code

Future<ImageUploadModel> postImage(File photoPath) async {
    ImageUploadModel imageUploadModel;

    var request = http.MultipartRequest(
        "POST", Uri.parse("my_api_url"));

    request.files.add(http.MultipartFile.fromBytes(
        "photo", await File.fromUri(Uri.parse(photoPath.path)).readAsBytes(),
        contentType: MediaType('image', 'jpg')));

    final response = await request.send();

    Uint8List responseByteArray = await response.stream.toBytes();

return standardSerializers.deserializeWith(ImageUploadModel.serializer, json.decode(utf8.decode(responseByteArray)));
  }

I tried uploading image using Postman and the image get uploaded properly.

I have followed the links on stack but I am not able to resolve the error

Flutter: http post upload an image Flutter how to send multiple files to http post How to send an image to an api in dart/flutter? How to upload image in Flutter?

I am getting a status code of 200 but when I tried to access any variable from the response I get empty string.

I tried with Native Android using Kotlin and Retrofit and it works properly

I also tried the Dio library

Dio dio = Dio();
    FormData formdata = FormData();

    formdata.add("photo", UploadFileInfo(photoPath, basename(photoPath.path)));
    dio
        .post("My_API_URL",
            data: formdata,
            options: Options(
                method: 'POST',
                responseType: ResponseType.json // or ResponseType.JSON
                ))
        .then((response) {
      print("2 $response");
      return standardSerializers.deserializeWith(
          ImageUploadModel.serializer, json.decode(response.data));
    }).catchError((error) => print("3 $error"));

I don't want to convert my image to base64

2 Answers2

3

I finally figured it out. Following code works for me.

var request = http.MultipartRequest(
        "POST", Uri.parse("MY_API_URL"));
    var multipartFile = await http.MultipartFile.fromPath(
        "photo", photoPath.path,
        contentType: MediaType('image', 'jpeg'));
    request.files.add(multipartFile);
    http.StreamedResponse response = await request.send();
    var responseByteArray = await response.stream.toBytes();

    return ImageUploadModel.fromJson(
        json.decode(utf8.decode(responseByteArray)));

Just change the MediaType according to your requirements

0

The response is a stream and therefore asynchronous. You are returning imageUploadModel before it gets a value assigned to it. Try the code below:

Uint8List responseByteArray = await response.stream.toBytes();

return standardSerializers.deserializeWith(ImageUploadModel.serializer, json.decode(utf8.decode(responseByteArray)));
Ovidiu
  • 8,204
  • 34
  • 45
  • I am getting empty response from server. I am pretty sure there is no error in the API as I checked it with postman. –  Jul 12 '19 at 12:11
  • Then there is a problem with your server endpoint as well - it should not return 200 and empty response. You will not be able to accurately determine what the issue is in your Flutter code until your server becomes consistent with responses. – Ovidiu Jul 12 '19 at 12:22
  • I had a talk with my backend engineer and he said the image is not reaching the server –  Jul 12 '19 at 14:06
  • You could also use `MultipartFile.fromPath` seeing as you have the file path available, which will slightly shorten your code and possibly read the file more efficiently - but I doubt that will make a change to your problem. It's still definitely wrong for your endpoint to return a 200 if the file is not even reaching it. – Ovidiu Jul 12 '19 at 14:24
  • I had used MultipartFile.fromPath and even used the Dio library but I am facing the same issue –  Jul 12 '19 at 14:29
  • Would you be able to copy paste the code generated by Postman? That's usually my starting point when I get different results using the app. The 'Code' button is on the right side just below the 'Send' button. – Ovidiu Jul 12 '19 at 15:08
  • If image is successfully uploaded then response is as follows { "file_name": "1562943566.png", "file_url": "path_to_image\/1562943566.png", "error": "" } –  Jul 12 '19 at 15:19