Nest: Example of storing images with Mongoose and Nest.js

Created on 5 Oct 2018  路  9Comments  路  Source: nestjs/nest

Can I find somewhere an example of storing images with Mongoose and Nest.js, using the File Upload interceptor?

Thanks!

Most helpful comment

Hello @ArneTesch ! You should use stackoverflow for that kind of question. I already do this with Nest, you have to use MulterModule & MongooseModule.

You can inject the Mongoose Connection using the @InjectConnection() decorator.
This is not documented currently, i already made a pull request about this .

Then you can use any gridfs library, i made this one: mongo-gridfs, and use it in a service :

@Injectable()
export class FilesService {
  private fileModel: MongoGridFS;

  constructor(@InjectConnection() private readonly connection: Connection) {
    this.fileModel = new MongoGridFS(this.connection.db, 'images');
  }

  async readStream(id: string): Promise<GridFSBucketReadStream> {
    return this.fileModel.readFileStream(id);
  }

  async writeStream(stream, options?: IGridFSWriteOption): Promise<FileInfo> {
    return await this.fileModel
      .writeFileStream(stream, options)
      .then(FilesService.convertToFileInfo);
  }

  async findInfo(id: Types.ObjectId): Promise<FileInfo> {
    return await this.fileModel
      .findById(id.toHexString())
      .then(FilesService.convertToFileInfo);
  }

  public async writeFile(
    file: DiskFile,
    metadata?: Metadata,
  ): Promise<FileInfo> {
    return await this.fileModel
      .uploadFile(
        file.path,
        {
          filename: file.originalname,
          contentType: file.mimetype,
          metadata,
        },
        true,
      )
      .then(FilesService.convertToFileInfo);
  }


 // ...
}

And in your controller :

  @Post()
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(
    @UploadedFile() file: DiskFile,
  ): Promise<Image> {
    const createdFile = await this.filesService.writeFile(file, metadata);

  }

All 9 comments

Hello @ArneTesch ! You should use stackoverflow for that kind of question. I already do this with Nest, you have to use MulterModule & MongooseModule.

You can inject the Mongoose Connection using the @InjectConnection() decorator.
This is not documented currently, i already made a pull request about this .

Then you can use any gridfs library, i made this one: mongo-gridfs, and use it in a service :

@Injectable()
export class FilesService {
  private fileModel: MongoGridFS;

  constructor(@InjectConnection() private readonly connection: Connection) {
    this.fileModel = new MongoGridFS(this.connection.db, 'images');
  }

  async readStream(id: string): Promise<GridFSBucketReadStream> {
    return this.fileModel.readFileStream(id);
  }

  async writeStream(stream, options?: IGridFSWriteOption): Promise<FileInfo> {
    return await this.fileModel
      .writeFileStream(stream, options)
      .then(FilesService.convertToFileInfo);
  }

  async findInfo(id: Types.ObjectId): Promise<FileInfo> {
    return await this.fileModel
      .findById(id.toHexString())
      .then(FilesService.convertToFileInfo);
  }

  public async writeFile(
    file: DiskFile,
    metadata?: Metadata,
  ): Promise<FileInfo> {
    return await this.fileModel
      .uploadFile(
        file.path,
        {
          filename: file.originalname,
          contentType: file.mimetype,
          metadata,
        },
        true,
      )
      .then(FilesService.convertToFileInfo);
  }


 // ...
}

And in your controller :

  @Post()
  @UseInterceptors(FileInterceptor('file'))
  async uploadFile(
    @UploadedFile() file: DiskFile,
  ): Promise<Image> {
    const createdFile = await this.filesService.writeFile(file, metadata);

  }

Hello @quen2404,

Thanks for the help! Really appreciate this.

How can I use the @InjectConnection decorator?
I guess this not standard included in Nest.js?

Thanks!

This decorator is provided by the MongooseModule like @InjectModel() . So you only have to add it to depencencies:

npm install --save @nestjs/mongoose mongoose

Can you show me an example of your DiskFile interface?
When testing with Postman, how should the form-data looks like?
When I upload an image with Postman and do a POST, I get a "File Not Found" error.

DiskFile is an interface which match this : https://github.com/expressjs/multer#api
Here is a postman example:
image
Don't forget to declare & configure your MulterModule in your AppModule

Hi,

The error is caused because the file.path value is undefined.
I am very new with Mongo and Node.js, so I haven't experience with Multer and the configuration of it. I guess I am missing something in the configuration.

I just configured it like this:

MulterModule.registerAsync({
    useFactory: () => ({
    dest: '/upload',
}),

And this is the error, above the error, I did a console log of my file:
image

File not found is an exception raised by mongo-grifs if there is no file at the given path.
Verify the value of your file.path variable. and check on your disk if the file exists.
I don't use Async mode to configure MulterModule, just this:

MulterModule.register({
  dest: '/tmp/upload',
})

Please, use StackOverflow for such questions.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

artaommahe picture artaommahe  路  3Comments

cojack picture cojack  路  3Comments

mishelashala picture mishelashala  路  3Comments

KamGor picture KamGor  路  3Comments

tronginc picture tronginc  路  3Comments