Reputation: 1201
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});
}
Upvotes: 8
Views: 6342
Reputation: 60357
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:
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: {...},
})
]
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);
}
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 } ]
Upvotes: 8