Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nestjs multer get list of new file names after multer storage

I have this middleware that I use to upload files.

@Injectable()
export class FilesMiddleware implements NestMiddleware {

  private storage = multer.diskStorage({
    destination: (req, file, cb) => {
      cb(null, path.join(__dirname, '../../uploads/'));
    },
    filename: (req, file, cb) => {
      let extArray = file.mimetype.split("/");
      let extension = extArray[extArray.length - 1];
      cb(null, file.fieldname + '-' + Date.now() + '.' + extension)
    }
});

  resolve(...args: any[]): MiddlewareFunction {
    return (req, res, next) => {
      console.log(req.files);
      const upload = multer({storage: this.storage});
      upload.any();
      return next();
    }
  }
}

The problem that in my request, when I use req.files it gives me the original file names instead of the new file names (with date, etc like I set in the multer storage options).

Is there a way I can get the new file names multer just uploaded with the middleware?

@Post('upload')
@UseInterceptors(FilesInterceptor('files[]', 20, {}))
public async onUpload(@Request() req, @Response() res, @UploadedFiles() files) {
    const mediaResponse = await this.media.saveMedias(0, files);
    res.json({status: true});
}
like image 480
Ben Beri Avatar asked May 19 '19 12:05

Ben Beri


People also ask

How do I import a Multer module in nest?

Here you import the MulterModule from @nestjs/platform-express and add it to your imports statement. You also define the destination in which the files will be saved when an upload occurs. Note: This destination starts at the root path of the project, not the src folder.

How to create a fileserver in nestjs?

The first thing you need to do is create a Nestjs project that will hold our Fileserver. For that, you need to open your terminal and run the following command: nest new nest-file-uploading && cd nest-file-uploading This creates a new directory called nest-file-uploading and initializes it with a standard Nestjs configuration.

How do I upload files to nest using express?

To handle file uploading, Nest provides a built-in module based on the multer middleware package for Express. Multer handles data posted in the multipart/form-data format, which is primarily used for uploading files via an HTTP POST request. This module is fully configurable and you can adjust its behavior to your application requirements.

How do I serve a static file in nest?

Serving Static Files with Nest.js Serving your static files from Nest.js is quite simple. All you need to do is to add a route which accepts GET requests to our controller and sends the file back using the sendFile () method of the object decorated with the @Res decorator. Open the src/auth/auth.controller.ts file and add the following imports:


1 Answers

First of all: It does not make sense to both use multer via the built-in FilesInterceptor and a custom FilesMiddleware. Choose one of the following two options:

A) Use the built-in FilesInterceptor (recommended)

You can provide your storage configuration directly for each FilesInterceptor:

const storage = {...};

@Controller()
export class AppController {

  @Post('upload')
  @UseInterceptors(FilesInterceptor('files', 20, { storage }))
  public async onUpload(@UploadedFiles() files) {
    return files.map(file => file.filename);
  }
}

Or provide the default multer storage configuration by importing the MulterModule:

imports: [
  MulterModule.register({
    storage: {...},
  })
]

B) Using your own middleware (without FilesInterceptor)

Only use this if you need more flexibility than the FilesInterceptor provides. You can use a Promise to wait for the upload to finish. After the upload, you can access the new file names via req.files.

export class FilesMiddleware implements NestMiddleware {
  private storage = {...};

  async use(req, res, next) {
    const upload = multer({ storage: this.storage });
    // wait until upload has finished
    await new Promise((resolve, reject) => {
      upload.array('files')(req, res, err => err ? reject(err) : resolve());
    });
    // Then you can access the new file names
    console.log(req.files.map(file => file.filename));
    return next();
  }
}

Access the uploaded files in your controller via the request object:

@Post('upload')
public async onUpload(@Request() req) {
  return req.files.map(file => file.filename);
}

How to access the new file names?

You'll find the uploaded files in req.files (middleware) or @UploadedFiles() files (interceptor) as an array with the following structure:

[ { fieldname: 'files',
    originalname: 'originalname.json',
    encoding: '7bit',
    mimetype: 'application/json',
    destination: 'D:/myproject/src/uploads',
    // This is what you are looking for
    filename: 'files-1558459911159.json',
    path:
     'D:/myproject/src/uploads/files-1558459911159.json',
    size: 2735 } ]
like image 155
Kim Kern Avatar answered Nov 03 '22 00:11

Kim Kern