├── .gitignore ├── README.md ├── package.json └── src ├── config └── db.js ├── controllers ├── home.js └── upload.js ├── middleware └── upload.js ├── routes └── index.js ├── server.js └── views └── index.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | package-lock.json -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Node.js Upload multiple images to MongoDB example 2 | 3 | For more detail, please visit: 4 | > [How to upload/store images in MongoDB using Node.js & Express](https://bezkoder.com/node-js-upload-multiple-images-mongodb/) 5 | 6 | Front-end Apps to work with this Node.js Server: 7 | - [Angular 8 Client](https://bezkoder.com/angular-multiple-files-upload/) / [Angular 10 Client](https://bezkoder.com/angular-10-file-upload/) / [Angular 11 Client](https://bezkoder.com/angular-11-file-upload/) / [Angular 12 Client](https://bezkoder.com/angular-12-file-upload/) 8 | 9 | - [Angular Material 12](https://bezkoder.com/angular-material-12-file-upload/) 10 | 11 | - [Vue Client](https://bezkoder.com/vue-axios-file-upload/) / [Vuetify Client](https://bezkoder.com/vuetify-file-upload/) 12 | 13 | - [React Client](https://bezkoder.com/react-file-upload-axios/) / [React Hooks Client](https://bezkoder.com/react-hooks-file-upload/) 14 | 15 | - [Material UI Client](https://bezkoder.com/material-ui-file-upload/) 16 | 17 | More Practice: 18 | > [Node.js Express File Upload Rest API example (static folder)](https://bezkoder.com/node-js-express-file-upload/) 19 | 20 | > [Node.js Express File Upload with Google Cloud Storage example](https://bezkoder.com/google-cloud-storage-nodejs-upload-file/) 21 | 22 | > [Upload & resize multiple images in Node.js using Express, Multer, Sharp](https://bezkoder.com/node-js-upload-resize-multiple-images/) 23 | 24 | > [Node.js, Express & MongoDb: Build a CRUD Rest Api example](https://bezkoder.com/node-express-mongodb-crud-rest-api/) 25 | 26 | > [Server side Pagination in Node.js with MongoDB and Mongoose](https://bezkoder.com/node-js-mongodb-pagination/) 27 | 28 | > [Node.js + MongoDB: User Authentication & Authorization with JWT](https://bezkoder.com/node-js-mongodb-auth-jwt/) 29 | 30 | Associations: 31 | > [MongoDB One-to-One relationship tutorial with Mongoose examples](https://bezkoder.com/mongoose-one-to-one-relationship-example/) 32 | 33 | > [MongoDB One-to-Many Relationship tutorial with Mongoose examples](https://bezkoder.com/mongoose-one-to-many-relationship/) 34 | 35 | > [MongoDB Many-to-Many Relationship with Mongoose examples](https://bezkoder.com/mongodb-many-to-many-mongoose/) 36 | 37 | Integration (run back-end & front-end on same server/port) 38 | > [Integrate React with Node.js Restful Services](https://bezkoder.com/integrate-react-express-same-server-port/) 39 | 40 | > [Integrate Angular with Node.js Restful Services](https://bezkoder.com/integrate-angular-10-node-js/) 41 | 42 | > [Integrate Vue with Node.js Restful Services](https://bezkoder.com/serve-vue-app-express/) 43 | 44 | ## Project setup 45 | ``` 46 | npm install 47 | ``` 48 | 49 | ### Run 50 | ``` 51 | node src/server.js 52 | ``` 53 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "upload-multiple-images-mongodb", 3 | "version": "1.0.0", 4 | "description": "Node.js upload multiple files/images to MongoDB Demo", 5 | "main": "src/server.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [ 10 | "node", 11 | "upload", 12 | "multiple", 13 | "files", 14 | "images", 15 | "mongodb" 16 | ], 17 | "author": "bezkoder", 18 | "license": "ISC", 19 | "dependencies": { 20 | "cors": "^2.8.5", 21 | "express": "^4.17.1", 22 | "mongodb": "^4.1.3", 23 | "multer": "^1.4.3", 24 | "multer-gridfs-storage": "^5.0.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/config/db.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | url: "mongodb://localhost:27017/", 3 | database: "bezkoder_files_db", 4 | imgBucket: "photos", 5 | }; 6 | -------------------------------------------------------------------------------- /src/controllers/home.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | const home = (req, res) => { 4 | return res.sendFile(path.join(`${__dirname}/../views/index.html`)); 5 | }; 6 | 7 | module.exports = { 8 | getHome: home 9 | }; 10 | -------------------------------------------------------------------------------- /src/controllers/upload.js: -------------------------------------------------------------------------------- 1 | const upload = require("../middleware/upload"); 2 | const dbConfig = require("../config/db"); 3 | 4 | const MongoClient = require("mongodb").MongoClient; 5 | const GridFSBucket = require("mongodb").GridFSBucket; 6 | 7 | const url = dbConfig.url; 8 | 9 | const baseUrl = "http://localhost:8080/files/"; 10 | 11 | const mongoClient = new MongoClient(url); 12 | 13 | const uploadFiles = async (req, res) => { 14 | try { 15 | await upload(req, res); 16 | console.log(req.files); 17 | 18 | if (req.files.length <= 0) { 19 | return res 20 | .status(400) 21 | .send({ message: "You must select at least 1 file." }); 22 | } 23 | 24 | return res.status(200).send({ 25 | message: "Files have been uploaded.", 26 | }); 27 | 28 | // console.log(req.file); 29 | 30 | // if (req.file == undefined) { 31 | // return res.send({ 32 | // message: "You must select a file.", 33 | // }); 34 | // } 35 | 36 | // return res.send({ 37 | // message: "File has been uploaded.", 38 | // }); 39 | } catch (error) { 40 | console.log(error); 41 | 42 | if (error.code === "LIMIT_UNEXPECTED_FILE") { 43 | return res.status(400).send({ 44 | message: "Too many files to upload.", 45 | }); 46 | } 47 | return res.status(500).send({ 48 | message: `Error when trying upload many files: ${error}`, 49 | }); 50 | 51 | // return res.send({ 52 | // message: "Error when trying upload image: ${error}", 53 | // }); 54 | } 55 | }; 56 | 57 | const getListFiles = async (req, res) => { 58 | try { 59 | await mongoClient.connect(); 60 | 61 | const database = mongoClient.db(dbConfig.database); 62 | const images = database.collection(dbConfig.imgBucket + ".files"); 63 | 64 | const cursor = images.find({}); 65 | 66 | if ((await cursor.count()) === 0) { 67 | return res.status(500).send({ 68 | message: "No files found!", 69 | }); 70 | } 71 | 72 | let fileInfos = []; 73 | await cursor.forEach((doc) => { 74 | fileInfos.push({ 75 | name: doc.filename, 76 | url: baseUrl + doc.filename, 77 | }); 78 | }); 79 | 80 | return res.status(200).send(fileInfos); 81 | } catch (error) { 82 | return res.status(500).send({ 83 | message: error.message, 84 | }); 85 | } 86 | }; 87 | 88 | const download = async (req, res) => { 89 | try { 90 | await mongoClient.connect(); 91 | 92 | const database = mongoClient.db(dbConfig.database); 93 | const bucket = new GridFSBucket(database, { 94 | bucketName: dbConfig.imgBucket, 95 | }); 96 | 97 | let downloadStream = bucket.openDownloadStreamByName(req.params.name); 98 | 99 | downloadStream.on("data", function (data) { 100 | return res.status(200).write(data); 101 | }); 102 | 103 | downloadStream.on("error", function (err) { 104 | return res.status(404).send({ message: "Cannot download the Image!" }); 105 | }); 106 | 107 | downloadStream.on("end", () => { 108 | return res.end(); 109 | }); 110 | } catch (error) { 111 | return res.status(500).send({ 112 | message: error.message, 113 | }); 114 | } 115 | }; 116 | 117 | module.exports = { 118 | uploadFiles, 119 | getListFiles, 120 | download, 121 | }; 122 | -------------------------------------------------------------------------------- /src/middleware/upload.js: -------------------------------------------------------------------------------- 1 | const util = require("util"); 2 | const multer = require("multer"); 3 | const { GridFsStorage } = require("multer-gridfs-storage"); 4 | const dbConfig = require("../config/db"); 5 | 6 | var storage = new GridFsStorage({ 7 | url: dbConfig.url + dbConfig.database, 8 | options: { useNewUrlParser: true, useUnifiedTopology: true }, 9 | file: (req, file) => { 10 | const match = ["image/png", "image/jpeg"]; 11 | 12 | if (match.indexOf(file.mimetype) === -1) { 13 | const filename = `${Date.now()}-bezkoder-${file.originalname}`; 14 | return filename; 15 | } 16 | 17 | return { 18 | bucketName: dbConfig.imgBucket, 19 | filename: `${Date.now()}-bezkoder-${file.originalname}` 20 | }; 21 | } 22 | }); 23 | 24 | var uploadFiles = multer({ storage: storage }).array("file", 10); 25 | // var uploadFiles = multer({ storage: storage }).single("file"); 26 | var uploadFilesMiddleware = util.promisify(uploadFiles); 27 | module.exports = uploadFilesMiddleware; 28 | -------------------------------------------------------------------------------- /src/routes/index.js: -------------------------------------------------------------------------------- 1 | const express = require("express"); 2 | const router = express.Router(); 3 | const homeController = require("../controllers/home"); 4 | const uploadController = require("../controllers/upload"); 5 | 6 | let routes = app => { 7 | router.get("/", homeController.getHome); 8 | 9 | router.post("/upload", uploadController.uploadFiles); 10 | router.get("/files", uploadController.getListFiles); 11 | router.get("/files/:name", uploadController.download); 12 | 13 | return app.use("/", router); 14 | }; 15 | 16 | module.exports = routes; -------------------------------------------------------------------------------- /src/server.js: -------------------------------------------------------------------------------- 1 | const cors = require("cors"); 2 | const express = require("express"); 3 | const app = express(); 4 | const initRoutes = require("./routes"); 5 | 6 | var corsOptions = { 7 | origin: "http://localhost:8081" 8 | }; 9 | 10 | app.use(cors(corsOptions)); 11 | app.use(express.urlencoded({ extended: true })); 12 | initRoutes(app); 13 | 14 | let port = 8080; 15 | app.listen(port, () => { 16 | console.log(`Running at localhost:${port}`); 17 | }); 18 | -------------------------------------------------------------------------------- /src/views/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Node.js upload images 8 | 12 | 17 | 18 | 19 |
20 |
21 |
22 |

Node.js upload images - bezkoder.com

23 | 24 |
30 |
31 | 38 | 44 |
45 | 46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | 57 | 58 | 79 | 80 | 81 | --------------------------------------------------------------------------------