I am trying to upload an image retrieved with Expo's ImagePicker. Here is my React Native component:
import * as ImagePicker from "expo-image-picker";
const Foo = () => {
const [photoUri, setPhotoUri] = useState("");
const choosePhoto = async () => {
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
quality: 1,
});
setPhotoUri(result.cancelled ? "" : result.uri);
};
const uploadPhoto = async () => {
if (photoUri == "") {
return;
}
const formData = new FormData();
formData.append("photo", {
uri: photoUri,
name: "test",
type: "image/jpeg",
});
return await fetch(Constants.manifest.extra.UPLOAD_IMAGE_URI, {
method: "POST",
body: formData,
headers: {
// No header otherwise multer will complain about missing boundary
// "content-type": "multipart/form-data",
},
});
};
return (
<View>
<TouchableOpacity onPress={choosePhoto}>
<Text>Choose Photo</Text>
<TouchableOpacity onPress={uploadPhoto}>
<Text>Confirm Image</Text>
</TouchableOpacity>
</TouchableOpacity>
);
};
Here is my Express backend:
import * as express from "express";
import * as multer from "multer";
const app = express();
const fileUpload = multer();
app.post(
"/profile_image/upload",
fileUpload.single("photo"),
async (req, _res, _next) => {
console.log(req.body);
console.log(req.body.photo);
console.log(req.file);
}
);
app.listen(
{
port: 8000,
},
() => {
console.log("Started server!");
}
);
When I test this in the Web version and check my Chrome console, it shows that the request was made where the photo field is a string '[object Object]'.
Similarly my Express endpoint parses the field as a string:
[Object: null prototype] { photo: '[object Object]' }
[object Object]
undefined
Also, another weird thing is that the photoUri returned by ImagePicker, at least in the Web app, defaults to the base64 encoded version instead of the actual filepath. Not sure if this is intentional:
data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD//gA8Q1JFQVRPUjogZ2QtanBlZyB2MS4wICh1c2luZyBJSkcgSlBFRyB2NjIpLCBxdWFsaXR5ID0gMTAwCv/bAEMAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA...