Click here to Skip to main content
16,022,362 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more: , +
I am a beginner in flutter development, I want to get filePath from the image that I choose in the app, but after I choose the image, the path is always emptied automatically ( value = null ), I need the path to make a request to API, I hope there is someone that can help me to find the solution of this problem,

here is my code :
  1  // Auth Service
  2  class AuthService {
  3    static String? token;
  4    static String? bioDateId;
  5  
  6    final TokenManager tokenManager = TokenManager();
  7    final BiodateIdManager biodateIdManager = BiodateIdManager();
  8  
  9  
 10  // Update Bio
 11    Future<bool> updateBio({
 12      required String firstName,
 13      required String lastName,
 14      required String birthDate,
 15      required String gender,
 16      required String phone,
 17      required String address,
 18      required String province,
 19      required String regencies,
 20      required String institutionName,
 21      required String pupils,
 22      required String field,
 23      String? image,
 24      String? proof,
 25    }) async {
 26      String? token = await tokenManager.getToken();
 27      String? bioDateId = await biodateIdManager.getBiodateId();
 28      try {
 29        // Create a Map for form data
 30        Map<String, dynamic> formDataMap = {
 31          "firstName": firstName,
 32          "lastName": lastName,
 33          "birthDate": birthDate,
 34          "gender": gender,
 35          "phone": phone,
 36          "address": address,
 37          "province": province,
 38          "regencies": regencies,
 39          "institutionName": institutionName,
 40          "field": field,
 41          "pupils": pupils,
 42        };
 43  
 44        // Get MIME type for the files and add to formDataMap if not null
 45        if (proof != null && proof.isNotEmpty) {
 46          String? proofMimeType = lookupMimeType(proof);
 47          if (proofMimeType != null) {
 48            MultipartFile proofMultipartFile = await MultipartFile.fromFile(
 49              proof,
 50              filename: 'proof.png',
 51              contentType: MediaType.parse(proofMimeType),
 52            );
 53            formDataMap["proof"] = proofMultipartFile;
 54          } else {
 55            debugPrint('Invalid proof MIME type');
 56          }
 57        }
 58  
 59        if (image != null && image.isNotEmpty) {
 60          String? imageMimeType = lookupMimeType(image);
 61          if (imageMimeType != null) {
 62            MultipartFile imageMultipartFile = await MultipartFile.fromFile(
 63              image,
 64              filename: 'image.png',
 65              contentType: MediaType.parse(imageMimeType),
 66            );
 67            formDataMap["image"] = imageMultipartFile;
 68          } else {
 69            debugPrint('Invalid image MIME type');
 70          }
 71        }
 72  
 73        var response = await Dio().put(
 74          "http://myurl/update-biodate?id=$bioDateId",
 75          data: FormData.fromMap(formDataMap),
 76          options: Options(
 77            headers: {
 78              "Content-Type": "multipart/form-data",
 79              "Authorization": "Bearer $token"
 80            },
 81          ),
 82        );
 83  
 84        if (response.statusCode == 200) {
 85          // Update successful
 86          return true;
 87        } else {
 88          throw Exception('Failed to Update Bio : ${response.data['message']}');
 89        }
 90      } on DioException catch (e) {
 91        if (e.response?.statusCode == 400) {
 92          debugPrint('Error 400: ${e.response?.data}');
 93          throw Exception('Update Bio failed: ${e.response?.data['message']}');
 94        } else {
 95          debugPrint('Error: ${e.toString()}');
 96          throw Exception('Failed to Update Bio');
 97        }
 98      }
 99    }

  1  // UpdateUserController
  2  class UpdateUserController {
  3    final AuthService _authService = AuthService();
  4    UpdateUserModel updateUserModel = UpdateUserModel();
  5  
  6    TextEditingController firstNameController = TextEditingController();
  7    TextEditingController lastNameController = TextEditingController();
  8    TextEditingController birthDateController = TextEditingController();
  9    TextEditingController genderController = TextEditingController();
 10    TextEditingController phoneController = TextEditingController();
 11    TextEditingController addressController = TextEditingController();
 12    TextEditingController provinceController = TextEditingController();
 13    TextEditingController regenciesController = TextEditingController();
 14    TextEditingController imageController = TextEditingController();
 15    TextEditingController institutionNameController = TextEditingController();
 16    TextEditingController studyFieldController = TextEditingController();
 17    TextEditingController uniqueIdController = TextEditingController();
 18    TextEditingController proofController = TextEditingController();
 19  
 20    String? _selectedImagePath;
 21    String? _selectedProofPath;
 22  
 23    void setImagePath(String filePath) {
 24      _selectedImagePath = filePath;
 25      debugPrint('Selected image path set: $_selectedImagePath');
 26      // imageController.text = filePath;
 27    }
 28  
 29    void setProofPath(String filePath) {
 30      _selectedProofPath = filePath;
 31      debugPrint('Selected proof path set: $_selectedProofPath');
 32      // proofController.text = filePath;
 33    }
 34  
 35    void reset() {
 36      _selectedImagePath = null;
 37      _selectedProofPath = null;
 38      firstNameController.clear();
 39      lastNameController.clear();
 40      birthDateController.clear();
 41      genderController.clear();
 42      phoneController.clear();
 43      addressController.clear();
 44      provinceController.clear();
 45      regenciesController.clear();
 46      institutionNameController.clear();
 47      studyFieldController.clear();
 48      uniqueIdController.clear();
 49      imageController.clear();
 50      proofController.clear();
 51    }
 52  
 53    void dispose() {
 54      firstNameController.dispose();
 55      lastNameController.dispose();
 56      birthDateController.dispose();
 57      genderController.dispose();
 58      phoneController.dispose();
 59      addressController.dispose();
 60      provinceController.dispose();
 61      regenciesController.dispose();
 62      addressController.dispose();
 63      imageController.dispose();
 64      institutionNameController.dispose();
 65      studyFieldController.dispose();
 66      uniqueIdController.dispose();
 67      proofController.dispose();
 68      // Dispose other controllers
 69    }
 70  
 71    bool fileExists(String path) {
 72      return File(path).existsSync();
 73    }
 74  
 75    Future<void> updateBio(BuildContext context) async {
 76      // Tampilkan loading dialog
 77      DialogHelper.showLoading(context);
 78  
 79      String firstName = firstNameController.text.trim();
 80      String lastName = lastNameController.text.trim();
 81      String birthDate = birthDateController.text.trim();
 82      String gender = genderController.text.trim();
 83      String phone = phoneController.text.trim();
 84      String address = addressController.text.trim();
 85      String province = provinceController.text.trim();
 86      String regencies = regenciesController.text.trim();
 87      String institutionName = institutionNameController.text.trim();
 88      String studyField = studyFieldController.text.trim();
 89      String uniqueId = uniqueIdController.text.trim();
 90      String? image = _selectedImagePath;
 91      String? proof = _selectedProofPath;
 92  
 93      // Validate file paths
 94      if (proof != null && proof.isNotEmpty && !fileExists(proof)) {
 95        throw Exception('Proof file does not exist or is inaccessible');
 96      }
 97  
 98      if (image != null && image.isNotEmpty && !fileExists(image)) {
 99        throw Exception('Image file does not exist or is inaccessible');
100      }
101  
102      try {
103        bool bioUpdated = await _authService.updateBio(
104          firstName: firstName,
105          lastName: lastName,
106          birthDate: birthDate,
107          gender: gender,
108          phone: phone,
109          address: address,
110          province: province,
111          regencies: regencies,
112          institutionName: institutionName,
113          field: studyField,
114          pupils: uniqueId,
115          image: image,
116          proof: proof,
117        );
118        // Sembunyikan loading dialog setelah selesai
119        DialogHelper.hideLoading(context);
120  
121        if (bioUpdated) {
122          // Reset fields and values after successful update
123          reset();
124          // Navigate ke halaman setelah UpdateBio sukses (contoh: EduPassApp)
125          Navigator.push(
126              context,
127              MaterialPageRoute(
128                  builder: (context) => const EduPassApp(
129                        initialPageIndex: 4,
130                      )));
131          ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
132            content: Text('UpdateBio successful'),
133            duration: Duration(seconds: 1),
134          ));
135          debugPrint('UpdateBio successful');
136        } else {
137          // Menampilkan pesan kesalahan jika UpdateBio gagal
138          ScaffoldMessenger.of(context).showSnackBar(const SnackBar(
139            content: Text('UpdateBio failed'),
140            duration: Duration(seconds: 2),
141          ));
142          debugPrint('UpdateBio failed');
143        }
144      } catch (e) {
145        // Sembunyikan loading dialog jika terjadi exception
146        DialogHelper.hideLoading(context);
147  
148        // Tangani exception yang mungkin terjadi
149        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
150          content: Text('Error: $e'),
151          duration: const Duration(seconds: 2),
152        ));
153  
154        debugPrint('Error during UpdateBio: $e');
155      }
156    }
157  }

  1  // ProfileUserDetail
  2  class ProfileDetailUser extends StatefulWidget {
  3    const ProfileDetailUser({super.key});
  4  
  5    @override
  6    State<ProfileDetailUser> createState() => _ProfileDetailUserState();
  7  }
  8  
  9  class _ProfileDetailUserState extends State<ProfileDetailUser> {
 10    String? _selectedImagePath;
 11    String? _selectedBackgroundPath;
 12    final UpdateUserController updateController = UpdateUserController();
 13  
 14    void _handleImageSelected(String filePath) {
 15      setState(() {
 16        _selectedImagePath = filePath;
 17        updateController.setImagePath(filePath);
 18      });
 19      // Panggil metode di UpdateUserController untuk menyimpan file path
 20      // updateController.setImagePath(filePath);
 21      debugPrint('File path: $filePath');
 22    }
 23  
 24    void _handleBackgroundSelected(String filePath) {
 25      setState(() {
 26        _selectedBackgroundPath = filePath;
 27        updateController.setProofPath(filePath);
 28      });
 29      // Panggil metode di UpdateUserController untuk menyimpan file path
 30      // updateController.setImagePath(filePath);
 31      debugPrint('File path: $filePath');
 32    }
 33  
 34    @override
 35    Widget build(BuildContext context) {
 36      return ChangeNotifierProvider(
 37        create: (context) => ProfileUserController(),
 38        child: Consumer<ProfileUserController>(
 39          builder: (context, profileController, child) {
 40            if (profileController.isLoading) {
 41              return const Center(child: CircularProgressIndicator());
 42            }
 43  
 44            if (profileController.userData == null) {
 45              return ErrorScreen(onRetry: profileController.retryFetchUserData);
 46            }
 47  
 48            // Initialize UpdateUserController's text controllers with data from ProfileUserController
 49            updateController.firstNameController.text =
 50                profileController.userData!['biodate']['firstName'] ??
 51                    'First Name' ??
 52                    '';
 53            updateController.lastNameController.text =
 54                profileController.userData!['biodate']['lastName'] ?? '';
 55            String birthDate =
 56                profileController.userData!['biodate']['birthDate'] ?? '';
 57            if (birthDate.isNotEmpty) {
 58              updateController.birthDateController.text =
 59                  birthDate.substring(0, 10); // Format date
 60            }
 61  
 62            updateController.genderController.text =
 63                profileController.userData!['biodate']['gender'] ?? '';
 64            updateController.phoneController.text =
 65                profileController.userData!['biodate']['phone'] ?? '';
 66            updateController.addressController.text =
 67                profileController.userData!['biodate']['address'] ?? '';
 68            updateController.provinceController.text =
 69                profileController.userData!['biodate']['province'] ?? '';
 70            updateController.regenciesController.text =
 71                profileController.userData!['biodate']['regencies'] ?? '';
 72            updateController.institutionNameController.text =
 73                profileController.userData!['biodate']['institutionName'] ?? '';
 74            updateController.studyFieldController.text =
 75                profileController.userData!['biodate']['field'] ?? '';
 76            updateController.uniqueIdController.text =
 77                profileController.userData!['biodate']['pupils'] ?? '';
 78            // Use setImagePath function instead of directly assigning to imageController.text
 79            updateController.setImagePath(
 80                profileController.userData!['biodate']['image'] ?? '');
 81            updateController.setProofPath(
 82                profileController.userData!['biodate']['proof'] ?? '');
 83  
 84            return Scaffold(
 85              appBar: AppBar(
 86                backgroundColor: Colors.white,
 87                elevation: 0,
 88                leading: IconButton(
 89                  icon: const Icon(Icons.arrow_back, color: Colors.black),
 90                  onPressed: () {
 91                    Navigator.pushReplacement(
 92                      context,
 93                      MaterialPageRoute(
 94                        builder: (context) =>
 95                            const EduPassApp(initialPageIndex: 4),
 96                      ),
 97                    );
 98                  },
 99                ),
100                title: Text(
101                  'Profile',
102                  style: GoogleFonts.poppins(
103                    color: Colors.black,
104                    fontSize: 20,
105                    fontWeight: FontWeight.bold,
106                  ),
107                ),
108              ),
109              body: Container(
110                color: Colors.grey.shade100,
111                child: SingleChildScrollView(
112                  padding: const EdgeInsets.only(
113                      left: 16, right: 16, top: 16, bottom: 30),
114                  child: Column(
115                    children: [
116                      UserAvatarField(onFileSelected: _handleImageSelected),
117                      const SizedBox(height: 20),
118                      if (_selectedImagePath != null) ...[
119                        Text('Selected file: $_selectedImagePath'),
120                        // Jika Anda ingin menampilkan gambar yang diunggah
121                        Image.file(
122                          File(_selectedImagePath!),
123                          height: 200,
124                        ),
125                      ],
126                      const SizedBox(height: 16),
127                      ProfileTextField(
128                        label: 'Nama Depan',
129                        placeholder: 'John',
130                        controller: updateController.firstNameController,
131                      ),
132                      const SizedBox(height: 16),
133                      ProfileTextField(
134                        label: 'Nama Belakang',
135                        placeholder: 'Doe',
136                        controller: updateController.lastNameController,
137                      ),
138                      const SizedBox(height: 16),
139                      ProfileTextField(
140                        label: 'Email',
141                        placeholder: 'stevejobs@gmail.com',
142                        enabled: false,
143                        controller: TextEditingController(
144                          text: profileController.userData!['email'] ?? '',
145                        ),
146                      ),
147                      const SizedBox(height: 16),
148                      ProfileDateField(
149                        label: 'Select Date',
150                        placeholder: 'YYYY-MM-DD',
151                        controller: updateController.birthDateController,
152                      ),
153                      const SizedBox(height: 16),
154                      ElevatedButton(
155                        onPressed: () {
156                          debugPrint(
157                              'Selected Date: ${updateController.birthDateController.text}');
158                        },
159                        child: const Text('Print Selected Date'),
160                      ),
161                      const SizedBox(height: 16),
162                      DropdownField(
163                        label: 'Jenis Kelamin',
164                        items: const ['Pria', 'Wanita', ''],
165                        controller: updateController.genderController,
166                        onChanged: (value) {
167                          debugPrint(
168                              'Selected Gender: ${updateController.genderController.text}');
169                        },
170                      ),
171                      const SizedBox(height: 16),
172                      UploadImageField(onFileSelected: _handleBackgroundSelected),
173                      const SizedBox(height: 20),
174                      if (_selectedBackgroundPath != null) ...[
175                        Text('Selected file: $_selectedBackgroundPath'),
176                        // Jika Anda ingin menampilkan gambar yang diunggah
177                        Image.file(
178                          File(_selectedBackgroundPath!),
179                          height: 200,
180                        ),
181                      ],
182                      const SizedBox(height: 16),
183                      ProfileTextField(
184                        label: 'Provinsi',
185                        placeholder: 'California',
186                        controller: updateController.provinceController,
187                      ),
188                      const SizedBox(height: 16),
189                      ProfileTextField(
190                        label: 'Regencies',
191                        placeholder: 'San Francisco',
192                        controller: updateController.regenciesController,
193                      ),
194                      const SizedBox(height: 16),
195                      ProfileTextField(
196                        label: 'Nomor HP',
197                        placeholder: '08123456789',
198                        controller: updateController.phoneController,
199                      ),
200                      const SizedBox(height: 16),
201                      ProfileTextField(
202                        label: 'Alamat',
203                        placeholder: 'Jalan Jendral Sudirman No 1',
204                        controller: updateController.addressController,
205                      ),
206                      const SizedBox(height: 16),
207                      ProfileTextField(
208                        label: 'Nama Instansi',
209                        placeholder: 'Harvard University',
210                        controller: updateController.institutionNameController,
211                      ),
212                      const SizedBox(height: 16),
213                      ProfileTextField(
214                        label: 'Bidang Studi/Jurusan',
215                        placeholder: 'Teknik Informatika',
216                        controller: updateController.studyFieldController,
217                      ),
218                      const SizedBox(height: 16),
219                      ProfileTextField(
220                        label: 'NIM/NISN',
221                        placeholder: '123123123',
222                        controller: updateController.uniqueIdController,
223                      ),
224                      const SizedBox(height: 32),
225                      ElevatedButton(
226                        onPressed: () {
227                          updateController.updateBio(context);
228                          updateController.reset();
229  
230                          // String? image = _selectedImagePath;
231                          // String? proof = _selectedBackgroundPath;
232                          // updateController.updateBio(context, image, proof);
233                        },
234                        style: ElevatedButton.styleFrom(
235                          backgroundColor: Colors.indigo,
236                          padding: const EdgeInsets.symmetric(
237                              horizontal: 40, vertical: 16),
238                          shape: RoundedRectangleBorder(
239                            borderRadius: BorderRadius.circular(8),
240                          ),
241                        ),
242                        child: Text(
243                          'Edit',
244                          style: GoogleFonts.poppins(
245                            fontSize: 16,
246                            fontWeight: FontWeight.bold,
247                            color: Colors.white,
248                          ),
249                        ),
250                      ),
251                    ],
252                  ),
253                ),
254              ),
255            );
256          },
257        ),
258      );
259    }
260  }

and here is the image of my debugging for imagePath, i hope you can get the picture of the problem

https://i.sstatic.net/8Lw0pyTK.png[^]

What I have tried:

I have tried to change the nullable type but it still not work
Posted
Updated 7-Jul-24 21:42pm
v2
Comments
Dave Kreskowiak 8-Jul-24 10:33am    
I don't do Dart/Flutter, but if you're trying to get the path a file was uploaded from on the client, you can't. Browsers haven't sent path information for uploaded files in quite a long time now as it is considered a security risk.

1 solution

First thing that stands out is that you check that the image is NOT NULL and throw an exception if it is NOT NULL (if the image is valid):
So, your code says, "if the image contains something besides null then throw an exception.
That is backwards.

Java
// Validate file paths
if (proof != null && proof.isNotEmpty && !fileExists(proof)) {
    throw Exception('Proof file does not exist or is inaccessible');
  }
 
    if (image != null && image.isNotEmpty && !fileExists(image)) {
     throw Exception('Image file does not exist or is inaccessible');
     }
 
Share this answer
 
Comments
Dzikry Habibie 8-Jul-24 10:06am    
Thank you for helping me
raddevus 8-Jul-24 16:44pm    
Glad to help. Was my answer the solution? Just curious. Thanks
UPDATE - oh, I see you marked it as the solution. I'm glad it solved it for you. 👍🏽

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900