How to send file using Chopper?

2,464

Solution 1

I was managed to upload file using http instead of Chopper.

   Future<http.Response> createPlan(String name, String path) async {
        var request = http.MultipartRequest(
            "POST",
            Uri.parse(
                "http://xxx"));

        request.fields['name'] = name;
        request.files.add(await http.MultipartFile.fromPath(
          'image',
          path,
        ));

        try {
          var streamedResponse = await request.send();
          var response = http.Response.fromStream(streamedResponse);
          return response;
        } catch (e) {
         rethrow;
        }
      }

Solution 2

Looking at the documentation for Chopper, the PartFile annotation supports three data types:

  • List<int>
  • String (path of your file)
  • MultipartFile (from package:http)

You are currently using String, but for reasons unknown it is not working for you. The first option would probably be the most straightforward, but the third option would be the most similar to what you currently have in Retrofit, so we could try that.

import 'package:http/http.dart';

...

Future<Response> createPlan(BuildContext context, String name, String path) async {
  Response response;
  try {
    final bytes = (await File(path).readAsBytes()).toList();
    final file = MultipartFile.fromBytes('image', bytes);
    response = await _service.createPlan(
      name,
      file,
    );
    return response;
  } catch (e) {
    rethrow;
  }
}

Service

@Post(path: "create_plan")
@multipart
Future<Response> createPlan(
  @Field('name') String name,
  @PartFile('image') MultipartFile image,
);
Share:
2,464
Hoo
Author by

Hoo

Updated on December 01, 2022

Comments

  • Hoo
    Hoo over 1 year

    In my kotlin project, I use retrofit and it works well.

    suspend fun createPlan(
        context: Context?,
        name: String,
        file: File?
    ): ABC? {
    
        val fileSignImage = file?.let {
            MultipartBody.Part.createFormData(
                "image",
                it.getName(),
                RequestBody.create("image/*".toMediaTypeOrNull(), it)
            )
        }
    
        return RetrofitFactory.apiCall(context) {
            RetrofitFactory.makeRetrofitService().createPlan(
                name.toRequestBody("text/plain".toMediaTypeOrNull()),
                fileSignImage
            )
        }} 
    

    RetrofitService

    @Multipart
    @POST("create_plan")
    fun createPlan(
        @Part("name") name: RequestBody,
        @Part image: MultipartBody.Part?
    ): Deferred<Response<WebApiResponse.ABCs>>
    

    If I want to use Chopper, what is the correct way?

    This is what I have tried

    Future<Response> createPlan(
          BuildContext context, String name,String path) async {
        Response response;
        try {
          response = await _service.createPlan(
               name,path);
          return response;
        } catch (e) {
          rethrow;
        }
      }
    

    Service

    @Post(path: "create_plan")
    @multipart
    Future<Response> createPlan(
    @Field('name') String name,@PartFile('image') String imagePath);
    

    How can I convert the imagePath to file so I can pass it as file to server using Chopper?

    Anyone?