I want to upload image in mongoose database along with other room information using Buffer and Express.Multer.File in nestjs. Image show in the uploads folder in the project directory but showing error that image is required and data is not uploading to the mongoose.
The Code of room.cshema.ts is:
import { Prop, Schema, SchemaFactory } from "@nestjs/mongoose";
import mongoose, { Document } from "mongoose";
import { Booking } from "src/book/schemas/booking.schema";
import { guest } from "src/guests/schemas/guests.schema";
@Schema({
timestamps: true,
})
export class rooms extends Document{
@Prop({required: true})
roomNo: number
@Prop({required: true})
type: string
@Prop({required: true})
price: number
@Prop({required: true})
status: boolean
@Prop({required: true})
description: string
@Prop({ required: true})
image: Buffer;
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'guests' })
guest: guest;
@Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'bookings' })
booking: Booking;
}
export const RoomSchema = SchemaFactory.createForClass(rooms)
The Code of room.service.ts is:
import { Injectable, UnauthorizedException } from '@nestjs/common';
import mongoose from 'mongoose';
import { rooms } from './schemas/schema.room';
import { InjectModel } from '@nestjs/mongoose';
import { RoomDto } from './dto/room.dto';
@Injectable()
export class RoomService {
constructor(
@InjectModel(rooms.name)
private RoomModel: mongoose.Model<rooms>
){}
async findAll(): Promise<rooms[]>{
const rooms = await this.RoomModel.find();
return rooms;
}
async create( room: rooms, images: Express.Multer.File): Promise<rooms>{
if(!images){
throw new UnauthorizedException("image not found")
}
room.image = images.buffer;
const res = await this.RoomModel.create(room);
return res;
}
}
The Code of room.controller.ts is:
import { Body, Controller, Get, Param, Post, Req, UploadedFile, UseInterceptors } from '@nestjs/common';
import { RoomService } from './room.service';
import { rooms } from './schemas/schema.room';
import { FileInterceptor } from '@nestjs/platform-express';
import { diskStorage } from 'multer';
@Controller('room')
export class RoomController {
constructor(
private roomService: RoomService
){}
@Get()
async getAllrooms(): Promise<rooms[]>{
return this.roomService.findAll()
}
@Post()
@UseInterceptors(
FileInterceptor('image', {
storage: diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1e9);
cb(null, file.fieldname + '-' + uniqueSuffix);
},
}),
}),
)
async createrooms(
@Body()
room,
@UploadedFile() images: Express.Multer.File,
): Promise<rooms>{
return this.roomService.create( room, images );
}
}
And here is the screenshot of postman page:
As is mentioned in Multer's documentation, the .buffer
property only exists when you save the file to memory. As you are using the DiskStorage
, there is no .buffer
and so when you create your Room
object in mongoose, there's a validation error because you are passing undefined
.
If you are already saving the file to disk, you should save the file path to your database, so that you can retrieve the file's binary data at a later point without slowing down the database in its retreival