Reputation: 1
It seems like the backend is receiving an empty request (Request Data: ) despite my app sending the data. This indicates that the FormData is not being sent properly or is empty when it reaches the backend.Also when i send data without file/logo and the multpart form data header they works here my client and server side code
public function update(Request $request, $id)
{
// Log incoming data for debugging
\Log::info('Request Data:', $request->all());
//i receive [2025-01-31 10:06:54] local.INFO: Request Data:
// Validate incoming data
$validator = Validator::make($request->all(), [
'name' => 'required|string|max:255',
'logo' => 'nullable|image|mimes:jpeg,png,jpg|max:526', // Un-commented logo validation
'location' => 'nullable|string|max:255',
'phone_number' => 'nullable|regex:/^\d{10,13}$/',
'email' => 'nullable|string|email|max:255',
]);
if ($validator->fails()) {
return response()->json($validator->errors(), 422); // Validation error
}
// Fetch the shop from the authenticated user's shops
$shop = Auth::user()->shops()->where('id', $id)->first();
// Check if shop exists and belongs to the authenticated user
if (!$shop) {
return response()->json(['message' => 'Shop not found!'], 404);
}
// Initialize validated data
$validated = $validator->validated();
// Handle the logo upload if it exists
if ($request->hasFile('logo')) {
// Get the logo file from the request
$logo = $request->file('logo');
// Ensure the file is valid
if ($logo->isValid()) {
// Generate a unique name for the logo file
$logoName = time() . '.' . $logo->getClientOriginalExtension();
// Store the logo in public storage and get its path
$logoPath = $logo->storeAs('public/logos', $logoName);
// Update the validated data with the logo path (relative to public storage)
$validated['logo'] = 'storage/logos/' . $logoName;
} else {
return response()->json(['message' => 'Logo upload failed!'], 500);
}
}
// Update the shop with validated data
$shop->update($validated);
// Return a successful response with updated shop information
return response()->json([
'message' => 'Shop updated successfully',
'shop' => $shop,
]);
}
While frontend look like
// Open the modal to edit shop details
const openEditModal = (shop) => {
setShopToEdit(shop);
setUpdatedShopDetails({
name: shop.name,
location: shop.location,
phone_number: shop.phone_number,
email: shop.email
});
setErrors({});
setSelectedLogo(null); // Reset selected logo when opening the edit modal
setIsModalVisible(true);
};
// Pick an image for the logo
const pickImage = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: 'images',
allowsEditing: true,
quality: 1,
});
if (!result.canceled) {
setSelectedLogo(result.assets[0]); // Store the selected logo image
}
};
// Handle updating the shop
const handleUpdateShop = async () => {
const token = await getAuthToken();
if (!token || !shopToEdit) return;
let validationErrors = {};
if (!updatedShopDetails.name) validationErrors.name = 'Name is requiredx.';
if (Object.keys(validationErrors).length > 0) {
setErrors(validationErrors);
Toast.show({
type: 'error',
text1: 'Please fill out all required fields',
position: 'bottom',
visibilityTime: 2000,
autoHide: true,
});
return;
}
try {
const formData = new FormData();
formData.append('name', updatedShopDetails.name);
formData.append('location', updatedShopDetails.location);
formData.append('phone_number', updatedShopDetails.phone_number);
formData.append('email', updatedShopDetails.email);
// If a logo was selected, append it to the FormData
if (selectedLogo) {
const logo = {
uri: selectedLogo.uri,
type: selectedLogo.mimeType || 'image/png',
name: selectedLogo.fileName || 'logo.png',
};
console.log('Appending logo:', logo); // Log the logo details to check
formData.append('logo', {
uri: logo.uri,
type: logo.type,
name: logo.name,
});
}
formData.forEach((value, key) => {
console.log('check if is key to value pair:', key, value);
});
//console.log('data:', formData);
await api.put(`/shops/${shopToEdit.id}`, formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});
setShops(shops.map(shop => {
if (shop.id === shopToEdit.id) {
return { ...shop, ...updatedShopDetails };
}
return shop;
}));
Toast.show({
type: 'success',
text1: 'Shop updated successfully',
position: 'bottom',
visibilityTime: 2000,
autoHide: true,
});
setIsModalVisible(false);
} catch (error) {
if (error.response) {
const { status, data } = error.response;
console.error('Error updating shop:', status, data);
Toast.show({
type: 'error',
text1: 'Error updating shop',
position: 'bottom',
visibilityTime: 2000,
autoHide: true,
});
} else {
// Handle the case where there's no response (network issues or something else)
console.error('Network or other error:', error);
Toast.show({
type: 'error',
text1: 'Network error. Please try again later.',
position: 'bottom',
visibilityTime: 2000,
autoHide: true,
});
}
}
};
the log look like
LOG check if is key to value pair: name sukus.
(NOBRIDGE) LOG check if is key to value pair: location Dubai
(NOBRIDGE) LOG check if is key to value pair: phone_number null
(NOBRIDGE) LOG check if is key to value pair: email [email protected]
(NOBRIDGE) LOG check if is key to value pair: logo {"name": "2469b768-2f52-40aa-952f-f7995bd82cc4.png", "type": "image/png", "uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252Fbizman-9889f099-e502-4c1d-9bf1-c4c27eb5030a/ImagePicker/2469b768-2f52-40aa-952f-f7995bd82cc4.png"}
(NOBRIDGE) ERROR Error updating shop: 422 {"name": ["The name field is required."]}
This happen while uploading image but if i remove code for images and use Accept:application/json it works
Upvotes: 0
Views: 33