How to add an image upload feature
We cannot store large files in MongoDB so we need to use Cloudinary to store media in their database.
What we need to do is;
- Setup our form to accept files
- Submit the form to hit one of our endpoints/routes
- Take the files and store in Cloudinary
- Cloudinary sends back URLs for the files
- We store the URLs in MongoDb
Multer Middleware
Default HTML forms accepts files but cannot send files.
In order to parse multipart forms we need to use the Multer middleware.
Multer adds a body object and a file or files object to the request object. The body object contains the
values of the text fields of the form, the file or files object contains the files uploaded via the
form.
- Set HTML form to have enctype: multipart/formdata to accept files
- Add a file input into HTML form
- Install Multer middleware package
- Require Multer
- Add upload.single or upload.array to the route
- Now our form can pass files along
Environment Variables (.env)
Environment variable files are files we store data in such as API keys and secrets for tools so when we puch code public, that data is not accessible.
- Make a .env file in the top level of our app.
- Install dotenv package
- Add the following at the top of app.js which only requires and accesses our env file if in
development mode so the public does not
if(process.env.NODE_ENV !== 'production') {
require('dotenv').config()
} - Add our API keys into the .env file
Uploading to Cloudinary
- Install the Cloudinary and Multer Storage Cloudinary packages
- require and execute the packages in a cloudinary config file.
- Set the cloudinary.config options to associate our account details.
- Add a new instance of a cloudinary storage
- Require the storage variable in the relevant routes file
- Pass the storage as the destination in Multer
Storing Cloudinary image links in our MongoDB
- Update the images field in the relevent model to add filename and path
- Update the route by mapping over the array of files to connect the filenames to the model
campground.images = req.files.map(f => ({
url: f.path,
filename: f.filename
}))
List of sources
- Colt Steeles web
developer bootcamp 2021