Using Jquery to Upload a File to Form in Node Js

Whenever nosotros submit a grade on the customer-side of any website, all the form data goes to the server-side. Commonly, form-information gets encoded before nosotros submit it to the server. Nosotros can do this by specifying the enctype aspect in the <form> tag in HTML.

If nosotros don't specify it, course-data gets encoded with the default blazon.

Introduction

This is commonly the case when we are dealing with text-merely data like name, email, password, etc. Only if we are uploading some kind of files, we need to specify the enctype attribute with the value "multipart/form-data". We need this value when we are using forms that accept a file upload command.

In this article, we will learn how we can upload files using node.js, express, and formidable. Formidable is a Node.js module for parsing class information, peculiarly file uploads.

Prerequisites

  1. Good understanding of Node.js and NPM.
  2. MongoDB must be installed in your device and y'all need to have a basic agreement of the database.
  3. Good understanding of the command line or integrated terminal in lawmaking editors.

Goals of this tutorial

  • How to design an API endpoint for posting multipart form data.
  • How to use Formidable to handle the file uploads.
  • How to manage and store those files on the server side.
  • How to view those files on the Frontend.

However, since half of these topics are already covered in my previous commodity, therefore I will refer to that commodity wherever it will be needed.

Project setup

For projection setup, you tin refer to my previous article. Y'all have to follow every step until I give the introduction to Multer.

The steps basically involved the post-obit:

  1. Binder Structure
  2. Setting up MongoDB with Mongoose and
  3. Rendering the HTML file.

Too, for reference. Your app.js file and folder construction should look like this.

app.js

Folder Structure:

            ├───model              (binder)              <br/> │ └───fileSchema.js              (file)              <br/> ├───node_modules              (folder)              <br/> ├───public              (folder)              <br/> │ └───css              (folder), files(folder)              <br/> |──────└───style.css              (file)              <br/> |───views              (folder)              <br/> │────└───index.ejs              (file)              <br/> ├───app.js              (file)              <br/> ├───package-lock.json              (file)              <br/> ├───package.json              (file)              <br/> ├───server.js              (file)              <br/>                      

Formidable

As mentioned previously, formidable is a Node.js module for parsing form data, particularly file uploads.

Let'southward outset by installing formidable.

Write this command in your last:

After installing the package, we will import information technology at the height of the app.js file:

                          const              formidable              =              crave("formidable");                      

Then we will create an API endpoint to upload the file.

Note: Brand sure that the endpoint used to return the page is at the finish of all the API endpoints.

                          // API Endpoint for uploading file                                          app.postal service("/api/uploadFile", (req,              res) => {              // Stuff to be added soon                            });                      

Let's start using formidable

The package works past creating an instance of the grade data that is coming from the client-side. It will be an object example with some default primal-value pairs that we can change following our requirements.

Allow'south have a look at information technology.

Add this piece of code in the in a higher place API callback function:

                          const              form              =              formidable.IncomingForm();              panel.log(course);                      

Nosotros can encounter the form information past sending the request with files on this API. Just, before that, nosotros need to make small changes in our HTML code i.e. in the index.ejs file.

Modify the value of the action attribute in the form to /api/uploadFile.

            <form              activity              =              "/api/uploadFile"              enctype              =              "multipart/form-information"              method              =              "POST">   <input              type              =              "file"              class              =              "admin__input"              id              =              "myFile"              proper name              =              "myFile"              />   <input              grade              =              "admin__submit"              type              =              "submit"              /> </form>                      

If y'all upload something from your rendered spider web folio afterward restarting your server, yous should see something like this on your terminal.

            IncomingForm              {              _events:              [Object: nil paradigm]              {},   _eventsCount: 0,   _maxListeners: undefined,   error: aught,   ended: false,   maxFields: chiliad,   maxFieldsSize: 20971520,   maxFileSize: 209715200,   keepExtensions: false,   uploadDir:              'C:\\Users\\SARTHA~1\\AppData\\Local\\Temp',   encoding:              'utf-8',   headers: zip,   type: null,   hash: false,   multiples: simulated,   bytesReceived: null,   bytesExpected: null,   _parser: null,   _flushing: 0,   _fieldsSize: 0,   _fileSize: 0,   openedFiles:              [],              [Symbol(kCapture)]: false              }                      

Every bit you can see, we accept many backdrop in this object including encoding, maxFileSize and then on. With these backdrop, we can configure formidable in our specification.

We accept to create a variable pointing to the directory/binder in which nosotros want to store the files. To do this, add the following lawmaking after creating the grade instance.

                          const              uploadFolder              =              path.join(__dirname,              "public",              "files");                      

Now, our uploadFolder variable points to the folder under the public directory which is present at the root level of our project.

Now allow's change the configuration by altering few properties in the form instance:

                          // Basic Configuration                                          class.multiples              =              truthful;              course.maxFileSize              =              50              *              1024              *              1024;              // 5MB                                          class.uploadDir              =              uploadFolder;              console.log(form);                      
  1. multiples belongings is set to fake past default as seen in the form object we logged in the panel. We tin set information technology to true and then that the user can add more than one file at once. Also, we take to add the multiple attributes in the input tag in the HTML to brand sure that the user is able to upload multiple files.

  2. We can restrict the size of the file that the user to uploads. Default is 200MB but we are limiting it to 5MB.

  3. And last but not least, we have to change the uploads directory to the one we created.

You can as well alter many other properties, but this is enough for most of the use cases.

If we log form instance in our panel one more time, we tin can meet the difference in the higher up-mentioned properties.

            IncomingForm              {              _events:              [Object: nada paradigm]              {},   _eventsCount: 0,   _maxListeners: undefined,   mistake: nix,   ended: false,   maxFields: k,   maxFieldsSize: 20971520,   maxFileSize: 52428800,   keepExtensions: faux,   uploadDir:              'D:\\Sarthak\\upload-multipart-form-data-using-formidable\\public\\files',   encoding:              'utf-8',   headers: cypher,   type: naught,   hash: simulated,   multiples: true,   bytesReceived: null,   bytesExpected: null,   _parser: null,   _flushing: 0,   _fieldsSize: 0,   _fileSize: 0,   openedFiles:              [],              [Symbol(kCapture)]: fake              }                      

Since nosotros are done with our basic configuration, nosotros can begin parsing our files. To do this, we use a built-in parsing function which we tin call on our course instance.

Add together this slice of code below configuration.

                          // Parsing                                          class.parse(req,              async              (err,              fields,              files) => {              panel.log(fields);              console.log(files);              if              (err) {              console.log("Mistake parsing the files");              return              res.status(400).json({              status              :              "Fail",              message              :              "At that place was an error parsing the files",              error              :              err,     });   } });                      

.parse(request, callback)

The "parse" function parses an incoming Node.js request containing grade data. If a callback is provided, all fields and files are collected and passed to the callback.

We aim to parse and store these files co-ordinate to our ain needs, thus we need to accept a look at them earlier we piece of work on them. Hence, we have ii log statements to take a expect at the data we get in the callback role.

As well, we will take care of whatsoever errors that may ascend at the very first step. This is because we do not want to parse any files with some potential errors. We do this by checking if in that location are whatsoever errors. If nosotros do encounter whatsoever, nosotros can send the response with a status code of 400, depicting a bad request.

If y'all run into this lawmaking by submitting a file, you will run into the log of parsed class data in the panel. Note that a new file will already take been created in your files folder nether public. Merely, that file will not be readable since there is no extension for the file yet.

Your logged data should look something like this.

                          {}              {              myFile: File              {              _events:              [Object: nil prototype]              {},     _eventsCount: 0,     _maxListeners: undefined,     size: 735154,     path:              'D:\\Sarthak\\upload-multipart-form-information-using-multer\\public\\files\\upload_d235df36a536ff3bc3cbfa8ac0f86e2f',     proper name:              'College ID.pdf',     blazon:              'application/pdf',     hash: null,     lastModifiedDate: 2021-05-30T12:40:05.872Z,     _writeStream: WriteStream              {              _writableState:              [WritableState],       _events:              [Object: null prototype]              {},       _eventsCount: 0,       _maxListeners: undefined,       path:              'D:\\Sarthak\\upload-multipart-form-data-using-multer\\public\\files\\upload_d235df36a536ff3bc3cbfa8ac0f86e2f',       fd: 4,       flags:              'due west',       fashion: 438,       start: undefined,       autoClose: true,       pos: undefined,       bytesWritten: 735154,       closed: false,              [Symbol(kFs)]:              [Object],              [Symbol(kCapture)]: false,              [Symbol(kIsPerformingIO)]: false              },              [Symbol(kCapture)]: false              }              }                      

The fields object is empty and we practise non want it. In the files object, we tin can see the name of the input tag (myFile) every bit we referred to in our HTML. We even have access to the name of the file with the original extension. All this information will assistance us save and manage our files more precisely.

Before moving ahead, we have to await at a special case. Since the user can upload multiple files at once, the incoming parsed information will exist an array of objects. So, nosotros have to bank check each fourth dimension if we are getting multiple files or single file before working on it further.

Data with multiple files looks something similar to this.

                          {              myFile:              [              File              {....},     File              {....}              ]              }                      

Next steps:

  1. Nosotros will handle single files and multiple files separately.
  2. In both scenarios, we will cheque if the file is valid by creating a dissever role.
  3. If the file isn't valid, then we will throw an error. If information technology is, we volition rename it and shop the file name in our database.

Now, add this piece of code and then we volition walk through each step.

                          // Check if multiple files or a single file                                          if              (!              files.myFile.length) {              //Single file                                          const              file              =              files.myFile;              // checks if the file is valid                                          const              isValid              =              isFileValid(file);              // creates a valid proper name by removing spaces                                          const              fileName              =              encodeURIComponent(file.name.replace(/\s/thousand,              "-"));              if              (!              isValid) {              // throes fault if file isn't valid                                          render              res.status(400).json({              status              :              "Neglect",              message              :              "The file type is not a valid type",     });   }              try              {              // renames the file in the directory                                          fs.renameSync(file.path,              join(uploadFolder,              fileName));   }              catch              (fault) {              console.log(error);   }              endeavour              {              // stores the fileName in the database                                          const              newFile              =              await              File.create({              proper noun              :              `files/              ${              fileName              }              `,     });              return              res.condition(200).json({              status              :              "success",              message              :              "File created successfully!!",     });   }              grab              (error) {              res.json({              mistake,     });   } }              else              {              // Multiple files                            }                      
  1. In the very first pace, nosotros are checking if the user has uploaded multiple files or not. We are doing this by checking the length of the myFile property in the files parsed data. If the length is cypher, then it ways just a single file has been uploaded.

  2. The adjacent step is to accept a await at whether the uploaded file is valid or not. We are doing this by creating a special role that goes like this.

                          const              isFileValid              =              (file) => {              const              blazon              =              file.blazon.split("/").pop();              const              validTypes              =              ["jpg",              "jpeg",              "png",              "pdf"];              if              (validTypes.indexOf(blazon)              ===              -              1) {              return              fake;   }              return              truthful; };                      

In this function, we are extracting the original extension of the file uploaded. If it exists in our described valid extensions array, then we tin can render truthful, otherwise we return simulated.

  1. Nosotros are creating a valid file name past removing all the "spaces" with "dashes". This is washed through the aid of Regular expressions and encodeURIComponent() function.

  2. If the file is not valid, nosotros are throwing an error. If it is, we are renaming the file in our files directory with the help of the fs module which is a core module in Node.js

Don't forget to import the fs module at the meridian of your file.

After that, we tin can shop the name of the file in our MongoDB cloud database that we hosted earlier in this tutorial.

Attempt completing the else cake for multiple files on your own! Here is the whole upload function for reference purposes.

app.js

With this, if you will endeavor to upload a file or prototype with a valid extension. It will be saved in your files directory with the name definition that we divers. As well, the file proper noun gets stored in your cloud database so that you can admission it on our front stop.

View these files on frontend

To learn how nosotros tin view these files, you can again refer to my previous article.

Formidable vs Multer

My preceding article was near Multer and this commodity is nigh Formidable. Both are npm packages even so ane serves equally a module and one as middleware.

I found formidable simpler to piece of work with due to the fact configuring multer is lot more complicated. But, there are some use instances where you will have to work with Multer.

For instance, if you cull to resize images before saving them on your server, then multer provides something known as a Buffer storage that tin assist you.

And then, it largely depends on your use case and what y'all find easier to use.

To learn almost this comparison in extra depth, you can refer to this article.

Happy coding!


Peer Review Contributions by: Linus Muema

nisbetficirdly.blogspot.com

Source: https://www.section.io/engineering-education/uploading-files-using-formidable-nodejs/

0 Response to "Using Jquery to Upload a File to Form in Node Js"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel