Zero Live
Zero Live

Reputation: 1843

flutter dio upload files [pdf/ docs]

I am trying to upload files using dio package in my flutter application. I am sending my files through formdata. Here is my implementation:

Future<FormData> formData1() async {
    return FormData.fromMap({
      "title": "from app2",
      "description": "app upload test",
      "files": [
        for (var i = 0; i < pathNames.length; i++)
          await MultipartFile.fromFile(pathNames[i],
              filename: fileNames[i])
      ]
    });
  }

Here is how I am sending my files.

_sendToServer() async {
    Dio dio = Dio(
      BaseOptions(
        contentType: 'multipart/form-data',
        headers: {
          "Authorization": "$token",
        },
      ),
    );
    dio.interceptors.add(
        LogInterceptor(requestBody: true, request: true, responseBody: true));
    FormData formData = await formData1();
    try {
      var response = await dio.post("http://url/api/upload",
          data: formData, onSendProgress: (int send, int total) {
        print((send / total) * 100);
      });
      print(response);
    } on DioError catch (e) {
      if (e.response != null) {
        print(e.response.data);
        print(e.response.headers);
        print(e.response.request);
      } else {
        print(e.request.headers);
        print(e.message);
      }
    }
  }

The other fields in formdata are sent to the server but not the multipartfile. When I try and do the same from postman form-data, it uploads correctly. Am I doing something wrong here?

Upvotes: 3

Views: 11946

Answers (5)

Kelwin Tantono
Kelwin Tantono

Reputation: 720

Here is my code where I used file_picker flutter library and MediaType('application', 'pdf') to ensure that the content passed to the API was indeed a .pdf file.

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:http_parser/http_parser.dart';

static Future<dynamic> uploadfile(int userid, File file, String token) async {
  var fileName = file.path.split('/').last;
  print(fileName);
  var formData = FormData.fromMap({
    'title': 'Upload Dokumen',
    'uploaded_file': await MultipartFile.fromFile(file.path,
        filename: fileName, contentType: MediaType('application', 'pdf')),
    "type": "application/pdf"
  });

  var response = await Dio().post('${urlapi}request/',
      options: Options(
          contentType: 'multipart/form-data',
          headers: {HttpHeaders.authorizationHeader: 'Token $token'}),
      data: formData);
  print(response);
  return response;
}

The file picker:

FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
  File file = File(result.files.single.path ??'file.pdf');
  BlocProvider.of<UploadCubit>(context)
                                   .uploadFile(statelogin.user.id, file,
                                          statelogin.user.token);
}

Upvotes: 2

Supun Dewapriya
Supun Dewapriya

Reputation: 763

Here you can use MultipartRequest class without using any of library to upload any kind of files using restAPI.

void uploadFile(File file) async {

    // string to uri
    var uri = Uri.parse("enter here upload URL");

    // create multipart request
    var request = new http.MultipartRequest("POST", uri);

    // if you need more parameters to parse, add those like this. i added "user_id". here this "user_id" is a key of the API request
    request.fields["user_id"] = "text";

    // multipart that takes file.. here this "idDocumentOne_1" is a key of the API request
    MultipartFile multipartFile = await http.MultipartFile.fromPath(
          'idDocumentOne_1',
          file.path
    );

    // add file to multipart
    request.files.add(multipartFile);

    // send request to upload file
    await request.send().then((response) async {
      // listen for response
      response.stream.transform(utf8.decoder).listen((value) {
        print(value);
      });

    }).catchError((e) {
      print(e);
    });
  }

I used file picker to pick file. Here is the codes for pick file.

Future getPdfAndUpload(int position) async {

    File file = await FilePicker.getFile(
      type: FileType.custom,
      allowedExtensions: ['pdf','docx'],
    );

    if(file != null) {

      setState(() {

          file1 = file; //file1 is a global variable which i created
     
      });

    }
  }

here file_picker flutter library.

Upvotes: 1

Adnan Kazi
Adnan Kazi

Reputation: 84

If you want to upload the file you can convert multipart array before calling API function because even if you put await in form data dio response will not wait for formdata object or you can use MultipartFile.fromFileSync() to get rid of await.

Let me show you in a simple way using my example. try to understand.

Multipart conversion

List multipartArray = [];
for (var i = 0; i < pathNames.length; i++){
   multipartArray.add(MultipartFile.fromFileSync(pathNames[i], filename: 
   basename(pathNames[i])));
}

Api side

static Future<Response> createPostApi(multipartArray) async {
    var uri = Uri.parse('http://your_base_url/post');
    return await Dio()
        .post('$uri',
            data: FormData.fromMap({
              "title": "from app2",
              "description": "app upload test",
              "files": multipartArray
            }))
        .catchError((e) {
      print(e.response.data);
      print(e.response.headers);
      print(e.response.request);
    });
  }

Upvotes: 3

Sreevardhan Reddy
Sreevardhan Reddy

Reputation: 731

// here attachmentFile is File instance, which is set by File Picker

Map<String, dynamic> _documentFormData = {};

if (attachmentFile != null) {
        _documentFormData['document_file'] = MultipartFile.fromFileSync(attachmentFile.path);
}
FormData formData = FormData.fromMap(_documentFormData);

try {
      var response = await dio.post("http://url/api/upload",
          data: formData, onSendProgress: (int send, int total) {
        print((send / total) * 100);
      });
      print(response);
    } on DioError catch (e) {
      if (e.response != null) {
        print(e.response.data);
        print(e.response.headers);
        print(e.response.request);
      } else {
        print(e.request.headers);
        print(e.message);
      }
    }

Upvotes: 1

Bhargav Sejpal
Bhargav Sejpal

Reputation: 1598

Change formdata with following rest is fine

   import 'package:path/path.dart' as pathManager;
    import 'package:mime/mime.dart' as mimeManager;

FormData formdata = FormData();

 formdata.add(
          "files",
          [UploadFileInfo(img, pathManager.basename(img.path),
          contentType:
              ContentType.parse(mimeManager.lookupMimeType(img.path)))]);

Upvotes: 1

Related Questions