Upload Image/File to Strapi (Flutter Web)
Asked Answered
B

4

8

I'm trying to upload an image to Strapi through Flutter Web. I'm aware (from this link) that I need to use FormData to do so. I've researched on many ways to do this and I stumble across Dio and of course Http.

Both solutions gave me errors: Unsupported operation: MultipartFile is only supported where dart:io is available.

I've tried this code:

var request = new http.MultipartRequest("POST", Uri.parse(url));
    request.files.add(
      await http.MultipartFile.fromPath(
        "files",
        imageFilePath,
      ),
    );
    request.send().then((response) {
      if (response.statusCode == 200) print("Uploaded!");
      print(response.statusCode);
    }).catchError((e) => print(e));

As suggested here.

And many other getting errors or Empty Data (400), when I use MultipartFile.fromBytes(...).

I'm just trying to upload a file, therefore I assume my body should only contain the FormData with as files as it's mentioned on Strapi's Documentation.

Bethelbethena answered 8/8, 2020 at 9:56 Comment(0)
B
9

So, I searched on the Flutter Discord for some help and I found out that my problem happens because Flutter Web can't use 'dart:io' , and using 'dart:html' takes away the use of all of Flutter's platforms.

I ended up using this imports:

import 'dart:convert';
import 'dart:typed_data';
import 'package:image_picker/image_picker.dart';
import 'package:http/http.dart' as http;
import 'package:http_parser/http_parser.dart';
import 'package:path/path.dart';
import 'package:async/async.dart';

and this is the function I created and worked:

 Future<bool> uploadImage(
    String imageFilePath,
    Uint8List imageBytes,
  ) async {
    String url = SERVERURL + "/uploadRoute";
    PickedFile imageFile = PickedFile(imageFilePath);
    var stream =
        new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));

    var uri = Uri.parse(url);
    int length = imageBytes.length;
    var request = new http.MultipartRequest("POST", uri);
    var multipartFile = new http.MultipartFile('files', stream, length,
        filename: basename(imageFile.path),
        contentType: MediaType('image', 'png'));

    request.files.add(multipartFile);
    var response = await request.send();
    print(response.statusCode);
    response.stream.transform(utf8.decoder).listen((value) {
      print(value); 
    });

I had this issue using Strapi and this solution worked like a charm.

Bethelbethena answered 4/9, 2020 at 14:37 Comment(3)
what is DelegatingStream ?Nostrum
The important bit for me was to add the content-type contentType: MediaType('image', 'png')Sal
i see, we change dart:io to dart:html is it okay in mobile when i change to dart:html?Poleaxe
A
2

Upload file during entry creation with Flutter

dio: ^3.0.10, mime: ^1.0.0 and http_parser.

The main part is the key name of the file if it's foo, so you have to change files.image with files.foo for file upload

final mimeType = mime.lookupMimeType(imageFile.path, headerBytes: [0xFF, 0xD8])?.split('/');

FormData formData = new FormData.fromMap(
  {
    "files.image": await MultipartFile.fromFile(
      imageFile.path,
      filename: imageFile.path.split('/').last,
      contentType: MediaType(mimeType?[0], mimeType?[1]),
    ),
    "data": jsonEncode({
      "title": title,
      "summary": summary,
      "content": content,
    }),
  },
);

Response response = await _dio.post(
  "/blogs",
  data: formData,
  options: Options(),
);
Agenda answered 8/4, 2021 at 18:37 Comment(2)
Error: Unsupported operation: MultipartFile is only supported where dart:io is available.Driftwood
Error: Unsupported operation: MultipartFile is only supported where dart:io is available.Gymnosophist
D
0

In Flutter Web:
I am using node.js with express as backend source I have created the following simple method to upload image and text data to localhost server using xamp

String url = 'http://localhost:8080/blog_upload';
    var request = http.MultipartRequest('POST', Uri.parse(url));
    imagebytes = await image.readAsBytes();
    List<int> listData = imagebytes!.cast();
    request.files.add(http.MultipartFile.fromBytes('field_name', listData ,
        filename:'myFile.jpg'));
 request.fields['name'] = 'Mehran Ullah Khan';
 request.fields['country'] = 'Pakistan';
    var response = await request.send();

I have used the following dependencies in the above method.

 http: ^0.13.3
 image_picker: ^0.8.2

how we used the image_picker? first globally declare image and imagebytes

image = await ImagePicker().pickImage(source: ImageSource.gallery);

And this is the method in the backend I have used.

app.post('/blog_upload', upload.single('field_name'), async (req, res, next) => {
  let data = {name_db: req.body['name'],    Country_db:req.body['country'],};
    let sqlq = `INSERT INTO TableName SET ? `;
    db.query(sqlq, data, (insertionErr, insertionResult) => {
      if (insertionErr) {
        console.log('failed_upload');
        throw insertionErr;
      }
      else {
        console.log('done_upload');
        res.send(insertionResult);  
      }
    });
  });

In the above method I have used multer and express packages You can see full details for multer and express in this link

Driftwood answered 24/7, 2021 at 6:50 Comment(0)
E
0

@Diego Cattarinich Clavel

How to this data upload to server can u say

String url = Constants.BASE_URL + HttpUrls.categories; PickedFile imageFile = PickedFile(path); var stream = new http.ByteStream(DelegatingStream.typed(imageFile.openRead()));

var uri = Uri.parse(url);
int length = imageBytes.length;
var request = new http.MultipartRequest(
  "PUT",
  uri,
);

var multipartFile = new http.MultipartFile(
  'files.categoryImage',
  stream,
  length,
  filename: basename(imageFile.path),
  contentType: MediaType('image', 'png'),
);

request.files.add(multipartFile);
request.fields['data'] = '{"category":$category}';
print(request.url);

var response = await request.send();
print(response.statusCode);
response.stream.transform(utf8.decoder).listen((value) {
  print(value);
});
Ember answered 17/8, 2021 at 12:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.