Email on Acid Upload Images File Name Is Invalid

NestJS File Uploading Using Multer

How to develop a uncomplicated file-uploading app

Photo by

This guide will prove you how yous tin can implement file uploading into your NestJS application and the things you should keep in heed when doing and then. You lot will develop an awarding with iii endpoints that will practise the following:

Function-1 upload paradigm to a server Directory

  • Upload an image;
  • Upload multiple images;
  • Get the paradigm using the image path.

function-two procedure uploaded stream without storing

  • Upload an epitome;
  • Upload multiple images;
  • Get the epitome using the image path.

You will besides add custom utilities to edit the file proper noun and validate the file upload for images.

So without wasting whatsoever farther time, allow's get into information technology.

Setup - Part-1 upload image to a server Directory

The first thing you demand to exercise is create a NestJS project that will hold our fileserver. For that, you need to open your terminal and run the following control:

              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.

With the directory in place, you can go alee and install the needed dependencies for the application using the post-obit commands:

              npm install @nestjs/platform-limited --save npm install @types/limited -D            

The last thing you lot need to practise before jumping into coding is create the files and folders needed for the project. This is very simple because the awarding just needs one more file.

              mkdir src/utils touch src/utils/file-uploading.utils.ts            

To first the app, you can now execute npm run start:dev in your last.

Uploading Files

Now that you take completed the setup process, you can go ahead and beginning implementing the actual functionality. Let'south get-go by importing the MulterModule in your AppModule and then you can use Multer in your other files.

                              import                {                Module                }                from                '@nestjs/common'                ;                import                {                AppController                }                from                './app.controller'                ;                import                {                MulterModule                }                from                '@nestjs/platform-limited'                ;                @Module                (                {                imports:                [MulterModule.                register                (                {                dest:                './files'                ,                }                )                ]                ,                controllers:                [AppController]                ,                }                )                consign                class                AppModule                {                }                          

Here you lot import the MulterModule from @nestjs/platform-express and add together information technology to your imports statement. You likewise define the destination in which the files volition exist saved when an upload occurs.

Note: This destination starts at the root path of the project, not the src folder.

The next footstep is to implement the bodily uploading functionality, which is rather simple. You simply need to add together a FileInterceptor() to a normal mail service request handler and then pull out the file from the request using the @UploadedFile() decorator.

              @Post                (                )                @UseInterceptors                (                FileInterceptor                (                'epitome'                )                ,                )                async                uploadedFile                (                @UploadedFile                  (                  )                  file                )                {                const                response                =                {                originalname:                file.originalname,                filename:                file.filename,                }                ;                return                response;                }                          

The FileInterceptor takes ii arguments: a fieldName and an optional options object, which you volition apply later to bank check for the correct file types and give the file a custom name in the directory.

Uploading multiple files at once is about the same; you just demand to utilize the FilesInterceptor instead and laissez passer an actress argument of the maximum number of files.

              @Mail service                (                'multiple'                )                @UseInterceptors                (                FilesInterceptor                (                'image'                ,                20                ,                {                storage:                diskStorage                (                {                destination:                './files'                ,                filename:                editFileName,                }                )                ,                fileFilter:                imageFileFilter,                }                )                ,                )                async                uploadMultipleFiles                (                @UploadedFiles                  (                  )                  files                )                {                const                response                =                [                ]                ;                files.                forEach                (                file                =>                {                const                fileReponse                =                {                originalname:                file.originalname,                filename:                file.filename,                }                ;                response.                push                (fileReponse)                ;                }                )                ;                return                response;                }                          

That was uncomplicated. The only problem here is that the user can upload every file type regardless of the file extension, which doesn't suit all projects and that the file proper name is just some random number.

Allow's fix that past implementing some utilities in your file-upload.utils.ts file.

First, permit'southward implement a file blazon filter that but allows images to exist uploaded.

                              export                const                imageFileFilter                =                (                req,                  file,                  callback                )                =>                {                if                (                !file.originalname.                match                (                /\.(jpg|jpeg|png|gif)$/                )                )                {                render                callback                (                new                Error                (                'Merely image files are allowed!'                )                ,                false                )                ;                }                callback                (                null                ,                true                )                ;                }                ;                export                const                editFileName                =                (                req,                  file,                  callback                )                =>                {                const                name                =                file.originalname.                divide                (                '.'                )                [                0                ]                ;                const                fileExtName                =                extname                (file.originalname)                ;                const                randomName                =                Assortment                (                4                )                .                fill up                (                nil                )                .                map                (                (                )                =>                Math.                circular                (Math.                random                (                )                *                xvi                )                .                toString                (                16                )                )                .                join                (                ''                )                ;                callback                (                aught                ,                                  `                                      ${proper name}                                    -                                      ${randomName}                                                        ${fileExtName}                                    `                                )                ;                }                ;                          

Hither yous create a middleware function, which checks if the file type is an image. If so it returns truthful, and the image will be uploaded. If not, you throw an mistake and return fake for the callback.

The editFileName* *function has the aforementioned structure just creates a custom filename using the original proper name, the file extension, and four random numbers.

Now that you have created these two middleware functions, it's time to use them in your app.controller.ts file. For that you lot just need to add together an extra configuration object to the FileInterceptor, which then looks similar this:

              @Post                (                )                @UseInterceptors                (                FileInterceptor                (                'image'                ,                {                storage:                diskStorage                (                {                destination:                './files'                ,                filename:                editFileName,                }                )                ,                fileFilter:                imageFileFilter,                }                )                ,                )                async                uploadedFile                (                @UploadedFile                  (                  )                  file                )                {                const                response                =                {                originalname:                file.originalname,                filename:                file.filename,                }                ;                return                response;                }                @Post                (                'multiple'                )                @UseInterceptors                (                FilesInterceptor                (                'paradigm'                ,                20                ,                {                storage:                diskStorage                (                {                destination:                './files'                ,                filename:                editFileName,                }                )                ,                fileFilter:                imageFileFilter,                }                )                ,                )                async                uploadMultipleFiles                (                @UploadedFiles                  (                  )                  files                )                {                const                response                =                [                ]                ;                files.                forEach                (                file                =>                {                const                fileReponse                =                {                originalname:                file.originalname,                filename:                file.filename,                }                ;                response.                button                (fileReponse)                ;                }                )                ;                return                response;                }                          

Lastly you will add a get road, which will accept the epitome path as an argument and return the prototype using the sendFile method.

                              @Get                (                ':imgpath'                )                seeUploadedFile                (@Param                (                'imgpath'                )                prototype,                @Res                (                )                res)                {                return                res.                sendFile                (prototype,                {                root:                './files'                }                )                ;                }                          

Testing the Application

Now that you accept finished your application, it'due south time to test it by sending an HTTP request to your endpoint. This can be done using the curlicue command in the final or by using an HTTP client software like Postman or Insomnia. I personally utilise Indisposition, but information technology should be well-nigh the same in Postman.

Beginning the server using the following command:

Every bit indicated by the terminal output, the server is at present running on http://localhost:3000. To exam the API you now only need to create a new HTTP request and change the request torso to multipart and so you can upload files.

role-2 process uploaded stream without storing

In this procedure where we merely need to upload and file and process on the fly and so we can utilize this On this instance we would not need mutler storage on server side so we don't demand MulterModule.annals anywhere in our code

Similar we will just upload and convert uploaded file to stream and procedure information technology without uploading or storing it on server

Lets write controller router for this

                              export                const                imageFileFilter                =                (                req:whatever,                  file:whatsoever,                  callback:any                )                =>                {                if                (                !file.originalname.                match                (                /\.(csv)$/                )                )                {                return                callback                (                new                Error                (                'But csv files are allowed!'                )                ,                false                )                ;                }                callback                (                null                ,                truthful                )                ;                }                ;                @Controller                (                '/api/v1/test/upload'                )                @ApiBearerAuth                (                'dominance'                )                @UsePipes                (                new                ValidationPipe                (                {                whitelist:                true                ,                transform:                true                ,                }                )                )                export                grade                UploadSupplierController                {                constructor                (                                  private                  readonly userSupplierProfileService:                  UserSupplierProfileService,                                )                {                }                @HttpCode                (HttpStatus.                OK                )                @ApiOkResponse                (                {                clarification:                RESULTS_RETURNED                }                )                @ApiBadRequestResponse                (                {                description:                PARAMETERS_FAILED_VALIDATION                }                )                @ApiTags                (                'examination'                )                @ApiConsumes                (                'multipart/form-data'                )                @uploadFile                (                'filename'                )                @Mail service                (                '/'                )                @UseInterceptors                (                FileInterceptor                (                'filename'                ,                {                fileFilter:                imageFileFilter,                }                )                ,                )                async                uploadedFile                (                @UploadedFile                  (                  )                  file:                  whatsoever,                  @Query                  (                  )                  params:                  UserSupplierParam,                  @User                  (                  )                  userId:                  string,                                )                {                try                {                if                (                !file)                {                throw                new                BadRequestException                (                'invalid file provided, immune *.csv single file'                )                ;                }                const                readStream                =                getStream                (file.buffer)                ;                await                this                .service.                create                (readStream,                params.id,                userId)                ;                return                {success:                true                }                }                grab                (err)                {                throw                err;                }                }                }                          

This controller can exist used to upload single file or multiple files, NestJS provided @annotations to manage all these things, We merely need to alter uploadFile to uploadFiles.

                              @ApiConsumes                (                'multipart/form-data'                )                @uploadFiles                (                'filename'                )                @Post                (                '/'                )                @UseInterceptors                (                FileInterceptor                (                'filename'                ,                {                fileFilter:                imageFileFilter,                }                )                ,                )                async                uploadedFiles                (                @UploadedFiles                  (                  )                  file:                  any,                  @Query                  (                  )                  params:                  UserSupplierParam,                  @User                  (                  )                  userId:                  string,                                )                {                try                {                if                (                !file)                {                throw                new                BadRequestException                (                'invalid file provided, immune *.csv unmarried file'                )                ;                }                const                readStream                =                getStream                (file.buffer)                ;                look                this                .service.                create                (readStream,                params.id,                userId)                ;                return                {success:                true                }                }                catch                (err)                {                throw                err;                }                }                }                          

We can read uploaded unmarried file stream or multiple file using buffer conversion to stream Now nosotros can uploads file and if file is not valid then nosotros tin throw exception for bad request

                              const                getStream                =                require                (                'into-stream'                )                ;                async                uploadedFile                (                @UploadedFile                  (                  )                  file:                  any,                  @Query                  (                  )                  params:                  UserSupplierParam,                  @User                  (                  )                  userId:                  string,                                )                {                endeavor                {                if                (                !file)                {                throw                new                BadRequestException                (                'invalid file provided, allowed *.csv single file'                )                ;                }                const                readStream                =                getStream                (file.buffer)                ;                look                this                .service.                create                (readStream,                params.id,                userId)                ;                return                {success:                truthful                }                }                catch                (err)                {                throw                err;                }                }                          

This is all we demand to setup file upload with or without server directory based upload, NestJS provided these cool @UploadFile annotations which actually helps to manage things like mutler equally its written on top of mutler, Nosotros can also pass mutler options while uploading

                              @Post                (                )                @UseInterceptors                (                FileInterceptor                (                'image'                ,                {                storage:                diskStorage                (                {                destination:                './files'                ,                filename:                editFileName,                }                )                ,                fileFilter:                imageFileFilter,                }                )                ,                )                          

If yous have any questions or feedback, permit me know.

hollowayovat1941.blogspot.com

Source: https://tkssharma.com/file-upload-feature-using-nestjs/

0 Response to "Email on Acid Upload Images File Name Is Invalid"

Postar um comentário

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel