I’m using a PUT request to upload user’s profile picture to s3 and save a link to it in my mongodb users collection. For some reason, I’m getting “CLIENT_ERROR”. Obviously, there’s some error in my implementation. Below are the steps i’ve taken and the code.
- use expo ImagePicker to select picture from a user’s media library
- in addition to selecting a picture, the selectImage function is meant to send a request the user endpoint using a usersApi
- in the usersApi, a storeProfPix function is to send a form data to the backend. The code works up to where the form data was created but the rest does not. Please help me out.
Here’s my code:
useEffect(() => {
requestPermission();
}, []);
const requestPermission = async () => {
const { granted } = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (!granted) alert("You need to enable permission to access the library.");
};
const handlePress = () => {
selectImage();
};
const selectImage = async () => {
try {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 0.5,
});
if (!result.cancelled) setImageUri(result.uri);
console.log("result from Picker: ", result);
console.log("user: ", user);
user.image = result;
const response = await usersApi.storeProfPix(user);
console.log("response from backend", response);
} catch (error) {
console.log("Error reading an image", error);
}
};
Here's the users Api
const storeProfPix = async (user) => {
const userId = user.userId;
let data = new FormData();
data.append("image", {
name: "image",
type: "image/jpeg",
uri: user.image.uri,
});
// The code works up to the above line
const profPix = await client.put(endpoint + "/" + userId, data); //this line is not working
console.log("profPix: ", profPix);
return profPix;
};
exports.s3UploadOne = async (file) => {
const s3 = new S3();
const param = {
Bucket: bucketName,
Body: fileStream,
Key: file.filename,
};
return await s3.upload(param).promise();
};
MIDDLEWARE - To Resize Image
module.exports = async (req, res, next) => {
const file = req.file;
const resizePromise = async (file) => {
await sharp(file.path).resize(360).jpeg({ quality: 50 });
};
await resizePromise();
req.file = file;
next();
};
USER ROUTE
router.put("/:id", [upload.single("image"), resizeOne], async (req, res) => {
const file = req.file;
console.log("file: ", file);
const data = await s3UploadOne(file);
console.log("data from s3: ", data);
try {
await User.findByIdAndUpdate(
{ _id: req.params.userId },
{
image: data.map((image) => ({ url: image.Location })),
}
);
// user.image = ;
// await user.save();
res.status(200).json("User image has been saved!");
} catch (err) {
res.status(500).json(err);
}
});
I have tried using a number of techniques to reach the backend but none is working.