My React Native application receives a selected image using the react-native-image-picker library and I need to send that image to a back-end running a NestJS server. The endpoint uses @UseInterceptor and FileInterceptor to extract the image from the 'file' field of the formData received. However, when I fire the request to the endpoint, the file received is undefined.
Here is my React Native code sending the request with the file in the FormData as a payload.
const uploadNewProfileImage = async () => {
if (!newProfileImage?.assets) return;
const formData = new FormData();
const profileImage = newProfileImage.assets[0];
console.log(profileImage);
if (profileImage.uri && user) {
formData.append(
'file',
JSON.stringify({
uri:
Platform.OS === 'android'
? profileImage.uri
: profileImage.uri.replace('file://', ''),
name: profileImage.fileName,
type: profileImage.type
})
);
client // client is an Axios instance that injects Bearer Token
.post(`/user/profile/${user.uid}/image`, formData)
.then(({ data }) => {
console.log(data);
})
.catch((err) => {
console.log(err.response);
setShowImageUploadError(true);
})
.finally(() => {
getUserProfile();
});
}
};
Here is my back-end NestJS code extracting the file.
// User.controller.ts
@UseGuards(UserGuard)
@ApiBearerAuth()
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
@UseInterceptors(FileInterceptor('file', { limits: { fileSize: 20000000 } }))
@Post('/profile/:uid/image')
@ApiOkResponse({ type: UploadProfileResponse })
@ApiBadRequestResponse({ description: 'Image too large OR Invalid image type' })
async uploadProfilePicture(@UploadedFile() file: Express.Multer.File, @Request() req): Promise<UploadProfileResponse> {
const uid = req.user.uid;
const imageUrl = await this.userService.uploadProfilePicture(uid, file);
return imageUrl;
}
}
I tried to set the axios request header in the axios config like so
{
headers: {
'Content-Type': 'multipart/form-data; boundary=——file'
}
}
I tried chaning the back-end endpoint to the following
@UseGuards(UserGuard)
@ApiBearerAuth()
@ApiUnauthorizedResponse({ description: 'Unauthorized' })
@UseInterceptors(FileFieldsInterceptor([{ name: 'file' }], { limits: { fileSize: 20000000 } }))
@Post('/profile/:uid/image')
@ApiOkResponse({ type: UploadProfileResponse })
@ApiBadRequestResponse({ description: 'Image too large OR Invalid image type' })
async uploadProfilePicture(@UploadedFiles() file: Array<Express.Multer.File>, @Request() req): Promise<UploadProfileResponse> {
const uid = req.user.uid;
console.log("File", file);
const imageUrl = await this.userService.uploadProfilePicture(uid, file[0]);
return imageUrl;
}
Nothing seems to be working, and the file extracted from the backend is still undefined.
Any help would be greatly appreciated.