0

I'm building edit screen where user can change Image. I would like user to display one of three images: - image from server - temporary image if previously not uploaded - new image to upload.

Problem appear when I'm going to display image from server. With use of future builder it's possible to display image but new image cannot be uploaded. If I'm not using future builder I get error

future is not subtype of type ImageProvider

My avatar for displaying images

 CircleAvatar(
       radius: MediaQuery.of(context).size.width / 6,
       backgroundColor: Colors.grey,
       backgroundImage: getImage(),
 ),

getImage()

getImage() {
    if (_image != null) {
      if (uploadCounter == 0) {
        uploadImage();
        AlertDialog(
          shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.all(Radius.circular(20.0))),
          backgroundColor: Colors.lightBlue[900],
          content: Container(
            child: Text('Uploading...'),
          ),
        );
      }
      return FileImage(_image);
    } else {
      return _emptyImage;
    }
}

And my upload image

uploadImage() async {
    if (_image == null) {
      showAlertDialog(
          context: context,
          title: "Error Uploading!",
          content: "No Image was selected.");
      return;
    } else {
      setState(() {
        uploadStatus = true;
      });

      final preffs = await SharedPreferences.getInstance();
      final token = preffs.getString('token');
      final id = preffs.getString('id');
      var uri = Uri.parse('http://10.0.2.2:8000/profiles/update/');
      var request = http.MultipartRequest('PUT', uri)
        ..fields['id'] = id
        ..headers.addAll({"Authorization": token})
        ..files.add(await http.MultipartFile.fromPath('image_1', _image.path));
      var response = await request.send();
      if (response.statusCode == 200) {
        print('Uploaded!');
        print(response);
      }
      setState(
        () {
          uploadStatus = false;
          uploadCounter = 1;
        },
      );
    }
}

I was trying to get image from server trough future builder or to save image before entering this screen then reload it from file, but saving files in flutter is not best solution I think

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
D. D.
  • 9
  • 1
  • your problem now is unable to fetch image from server or unable to save image ? – John Joe Jan 05 '23 at 15:07
  • I can fetch image from server. Problem is to display new image from image picker (when user choose new one) and upload new one on server. I little cheated by placing to widget. One is future builder with image from server second one is with empty image or new picked Image. In this config it's working but I got 2 CircleAvatars where second one size is set to 0.1 so its not visible. – D. D. Jan 05 '23 at 15:55
  • you can use `if-else` to check whether image is displayed from server or from image picker. If path contains `"https://"`, then it is from server, otherwise from image picker. – John Joe Jan 06 '23 at 03:27
  • Yes sure I was trying to do this. So I get the problem above. I was trying to put if-else inside of future builder of the widget but then for some reason picked image cannot be uploaded. And inside getImage() function and here I head conflict error "Future is not subtype of ImageProvider when returning image inside widget – D. D. Jan 07 '23 at 10:55
  • your `getImage` function used to get image from image picker, then upload to server? – John Joe Jan 07 '23 at 16:56
  • Function getImage returns image. If image was choosen by image Picker its returning and uploading file on server else its returning portrait icon image. Counter is made to upload image only once, otherwise its uploading infinite times – D. D. Jan 07 '23 at 22:30
  • what is `_image` ? Is it the image path? – John Joe Jan 08 '23 at 05:41
  • _image is a place holder for image from different sources. Type of that variable is File. You can access image form it by returning `FileImage(_image);` – D. D. Jan 09 '23 at 11:09
  • try print out `_image`. What value you see? You can use the path to indicate which is from image picker,which is from server. – John Joe Jan 09 '23 at 15:03

1 Answers1

0

The only solution works at the moment looks like this.

FutureBuilder<Profile>(
                      future: profileService.getProfile(),
                      builder: (context, snapshot) {
                        if (snapshot.hasData) {
                          profile = snapshot.data;
                          return CircleAvatar(
                            radius: MediaQuery.of(context).size.width / 6,
                            backgroundColor: Colors.grey,
                            backgroundImage: Image.network(
                                    "http://10.0.2.2:8000/" +
                                        profile.image_1.toString())
                                .image,
                          );
                        } else {
                          return Container();
                        }
                      }),
                  CircleAvatar(
                    radius: 0.1,
                    backgroundColor: Colors.grey,
                    backgroundImage: getImage(),
                  ),

If I put second CircleAvatar in return of if-else I get some problems Like no photo just gray Image etc, problem with upload photo.

D. D.
  • 9
  • 1