Closed 32penkin closed 6 years ago
What problem exactly do you have?
F.e. this is how we upload it in our app
Frontend
public async uploadFiles(payload: UploadFilesDto): Promise<boolean> {
const formData = new FormData();
formData.append("document", payload.file);
return await request(
`${API_URL}/document`,
{
method: "POST",
body: formData,
},
);
}
Backend Controller
@Post("document")
@HttpCode(HttpStatus.OK)
public async addDocument( @Request() req): Promise<any> {
const doc: Express.Multer.File = req.files.document[0];
....
}
Module
export class UserModule implements NestModule {
public configure(consumer: MiddlewaresConsumer) {
consumer
.apply(MulterMiddleware)
.with({
dest: "uploads",
} as multer.Options, [{
name: "document",
maxCount: 1,
}] as multer.Field[])
.forRoutes({
path: "v1/document",
method: RequestMethod.POST,
});
}
}
Hope it helps you.
@Jamakase Thanks for the answer! I was not very helped by your answer, could you please attach pieces of imports to your code as well as UploadFilesDto class? I've tried to do this by the approx similar way. Here it is my code, maybe someone will find any mistake :) Client side:
import { Component, OnInit } from '@angular/core';
import { CourseRepository } from '../../../@core/repositories/course/course.repository';
@Component({
selector: 'admin-learning',
template: `
<input type="file" (change)="fileChangeEvent($event)" placeholder="Upload file..."/>
<button type="button" (click)="upload()">Upload</button>
`,
})
export class AdminLearningComponent implements OnInit {
filesToUpload: Array<File> = [];
constructor(private courseRep: CourseRepository) {
}
ngOnInit() {
}
async upload() {
const formData: any = new FormData();
const files: Array<File> = this.filesToUpload;
formData.append('uploads', files);
const res = await this.courseRep.upload(formData);
}
fileChangeEvent(fileInput: any) {
this.filesToUpload = <Array<File>>fileInput.target.files;
}
}
Service:
async upload(file) {
return this.http.post(`${this.endpoint}/upload`, {data: file})
.map(res => res.json())
.map(json => json.data)
.toPromise();
}
And the server pieces:
Middleware:
import { Middleware } from '@nestjs/common';
import { NestMiddleware } from '@nestjs/common/interfaces/middlewares';
const multer = require('multer');
@Middleware()
export class FileUploadMiddleware implements NestMiddleware {
resolve(): (req, res, next) => void {
const upload = multer({ dest: './uploads/' });
return upload.any();
}
}
Module:
import { Module, RequestMethod } from '@nestjs/common';
import { DataBaseModule } from '../db/db.module';
import { LoggerModule } from '../logger';
import { CourseController } from './course.controller';
import { CourseService } from './course.service';
import { MiddlewaresConsumer } from '@nestjs/common/interfaces/middlewares';
import { FileUploadMiddleware } from '../middleware/file-upload.middleware';
@Module({
controllers: [ CourseController ],
components: [ CourseService ],
modules: [
LoggerModule,
DataBaseModule,
],
})
export class CourseModule {
configure(consumer: MiddlewaresConsumer) {
consumer.apply([
FileUploadMiddleware,
]).forRoutes({
method: RequestMethod.POST,
path: '/course/upload',
})
}
}
Controller:
@Post('/upload')
async testUpload(@Response() res, @Request() req, @Body('data') data) {
console.log(req.files);
console.log(data);
res.status(HttpStatus.OK).json({data: 'success'});
}
I'm not sure, maybe I've done something wrong on my client side? In advance thanks for the answer.
Hi @32penkin!
Did you manage to find a solution integrating Multer with Nestjs properly?
I have the same code from the referred #66 issue (that @kamilmysliwiec wrote), but the req.file
and req.files
properties are undefined
all the time. I send a valid multipart/form-data
request to the server using Postman but I can't make it to a processed file.
multer.middleware.ts
import { Middleware, NestMiddleware, ExpressMiddleware } from '@nestjs/common';
import * as multer from 'multer';
@Middleware()
export class MulterMiddleware implements NestMiddleware {
resolve(...args: any[]): ExpressMiddleware {
const upload = multer({ dest: './uploads/' });
/** Accept only one file, using the csv fieldname */
return upload.single('csv');
}
}
A module's configure method:
configure(consumer: MiddlewaresConsumer) {
consumer.apply(MulterMiddleware).forRoutes({
path: '/admin/campaign/:id/csv',
method: RequestMethod.PUT,
});
}
One of the method belonging to a controller which is imported by the module declaring the upper configure
method:
/** All controller methods are prefixed with admin/campaign */
@Put(':id/csv')
async handleUploadedCSV(@Req() req: Request, @Res() res: Response) {
console.log(`req.files`, req.files);
console.log(`req.file`, req.file);
/** Send 200 OK for now */
return res.sendStatus(HttpStatus.OK);
}
This is the screenshot of the actual Postman request I'm submitting to the server: There are no additional headers attached to the request.
Sorry for the long comment, but I really don't know what's missing.
Hmm...confusing. I've reloaded the test.csv
file in Postman and everything started working without any code modifications. Strange.
Hi,
Since v4.6.0
Nest comes with a basic multer
integration. Both @UploadedFile()
and FileInterceptor
are available from inside @nestjs/common
. They can be used in following way:
@Post()
@UseInterceptors(FileInterceptor('filename'))
async upload(@UploadedFile() file) {
console.log(file)
}
To upload multiple files, you can use @UploadedFiles()
and FilesInterceptor
. The interceptors accept options
object as an argument. The options schema is equal to multer
options schema.
Is it planned to add support for the any() function ?
@pterblgh how to fix , I have problem too.
@luanxuechao You should be good to go with @kamilmysliwiec's recommendation: https://github.com/nestjs/nest/issues/262#issuecomment-366098589
@pterblgh thank you, I fix it.
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.
Hi everyone! I use NesJSt in my project. Now I'm faced with the problem of uploading the file from the client. I already saw the existing Issue # 66, but that did not help me. It is difficult to formulate an issue, but maybe someone has a working example of NestJS + Multer + Angular2. In advance thanks for the answer.