Home > Mobile >  Unhandled Exception: Bad state: Can't finalize a finalized MultipartFile and only 1 image gets
Unhandled Exception: Bad state: Can't finalize a finalized MultipartFile and only 1 image gets

Time:06-19

Using DIO to upload images Data to my fastAPI. In my case, the data gets uploaded but only one image gets uploaded. And i recieve this Unhandled exception error in the debug console. Has anyone faced this issue recently? In the backend, i get the 201 created so the fastAPI backend works really well. Here is the upload method i am using:

  _uploadImage() async {
    for (int i = 0; i < imageFileList!.length; i  ) {
      var path = imageFileList![i].path;
      _images!.add(await MultipartFile.fromFile(
        path,
        // filename: path.split('/').last,
        // contentType: MediaType("image", "jpg")
      ));
      var formData = FormData.fromMap(
        {
          // need to await for this async operation
          "name": _pNameC.text,
          "price": _pPriceC.text,
          "description": _pDescriptionC.text,
          "files": _images,
        },
      );
      var response =
          await DioClient.dio.post("http://10.0.2.2:8000/products/addProductFD",
              data: formData,
              options: Options(
                  contentType: 'multipart/form-data',
                  followRedirects: false,
                  validateStatus: (status) {
                    return status! < 500;
                  }));

      debugPrint(response.toString());
    }
  }

The error i am getting:

I/flutter ( 9021): {"name":"ugu","price":25.0,"is_active":true,"imgs_url":["localhost:8000/static/product_images/30e2b2d6d58f8a23a5d6.jpg"],"id":11,"description":"kjhkaz","owner_id":null}
E/flutter ( 9021): [ERROR:flutter/lib/ui/ui_dart_state.cc(198)] Unhandled Exception: Bad state: Can't finalize a finalized MultipartFile.
E/flutter ( 9021): #0      MultipartFile.finalize
package:dio/src/multipart_file.dart:133

Please help!

CodePudding user response:

I was forcing the for loop to work not knowing that the DIO docs said that mapping the files to list is the correct way to upload multiple images. So i removed the for-loop and just mapped the images to list inside the form data and everyting is working fine now. Thanks to this post https://stackoverflow.com/a/64683825/12986987. My new upload code for Flutter(image_picker) to FastAPI is:

  _uploadImage() async {
    var formData = FormData.fromMap(
      {
        // need to await for this async operation
        "name": _pNameC.text,
        "price": _pPriceC.text,
        "description": _pDescriptionC.text,
        "files": imageFileList!
            .map((item) => MultipartFile.fromFileSync(item.path,
                filename: item.path.split('/').last))
            .toList()
      },
    );
    var response =
        await DioClient.dio.post("http://10.0.2.2:8000/products/addProductFD",
            data: formData,
            options: Options(
                contentType: 'multipart/form-data',
                followRedirects: false,
                validateStatus: (status) {
                  return status! < 500;
                }));
    debugPrint(_images!.join(","));
    debugPrint(response.toString());
  }

FastAPI Backend:

@router.post('/addProductFD', status_code=status.HTTP_201_CREATED)
async def create(
    name: str = Form(...),
    price: float = Form(...),
    description: str = Form(...),
    files: List[UploadFile] = File(...),
    db: Session = Depends(get_db),
    # current_user: Vendor = Depends(get_current_active_user)
):
    fileList = []
    for file in files:
        try:
            FILEPATH = "./static/product_images/"
            pimage_name = FILEPATH   imghex(file.filename)
            contents = await file.read()
            with open(pimage_name, 'wb') as f:
                f.write(contents)
        except Exception:
            return {"message": "There was an error uploading the file(s)"}
        finally:
            await file.close()
        fileList.append("localhost:8000"   pimage_name[1:])

    file_urls = ",".join(fileList)
    new_item = Product(
        name=name,
        price=price,
        description=description,
        imgs_url=[file_urls],
        # owner_id=current_user.id
    )

    db.add(new_item)
    db.commit()
    db.refresh(new_item)
    return new_item

For the image_picker in flutter:

  final ImagePicker imagePicker = ImagePicker();

  List<XFile>? imageFileList = [];

  void selectImages() async {
    final List<XFile>? selectedImages = await imagePicker.pickMultiImage();
    if (selectedImages!.isNotEmpty) {
      imageFileList!.addAll(selectedImages);
    }
    setState(() {});
  }

Thats all.

  • Related