5

I have a flutter app that interacts with a server through a REST api where it can fetch and display information. It can also send text information to the server. I want to add functionality of sending pdf files and images to the server but I dont know how to achieve that. Here is the code for selecting files

 @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Another Attempt'),
        centerTitle: true,
      ),
      body: Container(
        alignment: Alignment.topCenter,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            MaterialButton(
              onPressed: () async {
                FilePickerResult result =
                    await FilePicker.platform.pickFiles(allowMultiple: true);

                if (result != null) {
                  List<File> files =
                      result.paths.map((path) => File(path)).toList();
                } else {
                  // User canceled the picker
                }
              },
              child: Text('Upload multiple files'),
              color: Colors.blueAccent,
            ),
            SizedBox(height: 10.0),
            MaterialButton(
              onPressed: () async {
                FilePickerResult result = await FilePicker.platform.pickFiles();

                if (result != null) {
                  File file = File(result.files.single.path);
                } else {
                  // User canceled the picker
                }
              },
              child: Text('Upload single file'),
              color: Colors.blueAccent,
            ),
            SizedBox(height: 10.0),
            MaterialButton(
              onPressed: () {
                _submitData();
              },
              child: Text('Upload single file'),
              color: Colors.blueAccent,
            ),
          ],
        ),
      ),
    );
  }

 void _submitData() async {
    setState(() {});

    var data = {
      'image': file,
      'pdf': files,
     };


    try {
      var res = await Network().postData(data, '/convert-customer');
      var body = json.decode(res.body);
      if (res.statusCode == 200 || res.statusCode == 201) {
        print(res.statusCode);
        print(body);
      } else {}
    } on TimeoutException catch (_) {
      print("Your connection has timedout");
      _formKey.currentState.reset();
    } on SocketException catch (_) {
      print("You are not connected to internet");
      _formKey.currentState.reset();
    }

    setState(() {
      _isLoading = false;
    });
  }

Here is the code for sending data to the server


  final String _baseUrl = 'http://106.20.34.127/trial/api/v1';

  var token;

  _getToken() async {
    SharedPreferences localStorage = await SharedPreferences.getInstance();
    token = jsonDecode(localStorage.getString('token'))['token'];
  }
  postData(data, apiUrl) async {
    try {
      var _finalUrl = _baseUrl + apiUrl;
      Uri fullUrl = Uri.parse(_finalUrl);
      await _getToken();
      print(fullUrl);
      return await http.post(fullUrl,
          body: jsonEncode(data), headers: _setHeaders());
    } catch (e) {
      print(e);
    }
  }

How do I go about it.

1 Answer 1

16

Use http.MultipartRequest instead of http.post for files. Usually, the body of a POST request is made of textual key-value pairs. With a multipart POST request, you can also include files with binary content (images, various documents, etc.), in addition to the regular text values.

import 'package:http/http.dart' as http;

var req = http.MultipartRequest('POST', Uri.parse(url));

This req object has a member Map called fields for textual values and a List called files to which you can add MultipartFiles.

The most important element of this whole thing is the MultipartFile. It can be constructed in a few ways:

  1. The default MultipartFile(key, stream, length) constructor, which you can use if you need to create the file from a Stream of bytes of which we know the length.

  2. The MultipartFile.fromBytes(key, bytes) factory method, which attaches a file obtained from a List of bytes.

  3. The MultipartFile.fromString(key, string) factory method, which attaches a text file containing the string passed to it.

  4. The MultipartFile.fromPath(key, path) factory method, which attaches the file found at the given path.

Example: Using MultipartFile.fromPath() you could write a function like the following

  (String filename, String url) async {
  var request = http.MultipartRequest('POST', Uri.parse(url));
  request.files.add(
    await http.MultipartFile.fromPath(
      'pdf',
      filename
    )
  );
  var res = await request.send();
}

or you can simply use this multipart_request plugin available on pub.dev

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.