I am using mongodb atlas to store my data in cloud but i am unable to store it as i am getting the same error continuously
Error:The database connection must be open to store files
My server side code
const mongoURI = 'mongodb+srv://caman3874:qwertyuiopaman1234##amanco-pexfz.mongodb.net/test?retryWrites=true&w=majority';
const conn = mongoose.createConnection(mongoURI,{useNewUrlParser:true});
let gfs;
conn.once('open', () => {
gfs = Grid(conn.db, mongoose.mongo);
gfs.collection('uploads');
console.log("connection made successfully");
});
const storage = new GridFsStorage({
url: mongoURI,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
app.get('/',(req,res)=>{
res.render('index');
});
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ file: req.file });
});
const port = 5000;
app.listen(port, () => console.log(`Server started on port ${port}`));
My html code
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
</style>
<title>Mongo File Uploads</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-6 m-auto">
<form action="/upload" method="POST" enctype="multipart/form-data">
<div class="custom-file mb-3">
<input type="file" name="file" id="file" class="custom-file-input">
<label for="file" class="custom-file-label">Choose File</label>
</div>
<input type="submit" value="Submit" class="btn btn-primary btn-block">
</form>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
crossorigin="anonymous"></script>
</body>
</html>
Error: The database connection must be open to store files
at GridFSStorage._handleFile (C:\Users\91807\Desktop\mongo\node_modules\multer-gridfs-storage\lib\gridfs.js:339:17)
at C:\Users\91807\Desktop\mongo\node_modules\multer\lib\make-middleware.js:144:17
at allowAll (C:\Users\91807\Desktop\mongo\node_modules\multer\index.js:8:3)
at wrappedFileFilter (C:\Users\91807\Desktop\mongo\node_modules\multer\index.js:44:7)
at Busboy. (C:\Users\91807\Desktop\mongo\node_modules\multer\lib\make-middleware.js:114:7)
at Busboy.emit (events.js:209:13)
at Busboy.emit (C:\Users\91807\Desktop\mongo\node_modules\busboy\lib\main.js:38:33)
at PartStream. (C:\Users\91807\Desktop\mongo\node_modules\busboy\lib\types\multipart.js:213:13)
at PartStream.emit (events.js:209:13)
at HeaderParser. (C:\Users\91807\Desktop\mongo\node_modules\dicer\lib\Dicer.js:51:16)
at HeaderParser.emit (events.js:209:13)
at HeaderParser._finish (C:\Users\91807\Desktop\mongo\node_modules\dicer\lib\HeaderParser.js:68:8)
at SBMH. (C:\Users\91807\Desktop\mongo\node_modules\dicer\lib\HeaderParser.js:40:12)
at SBMH.emit (events.js:209:13)
at SBMH._sbmh_feed (C:\Users\91807\Desktop\mongo\node_modules\streamsearch\lib\sbmh.js:159:14)
at SBMH.push (C:\Users\91807\Desktop\mongo\node_modules\streamsearch\lib\sbmh.js:56:14)
const mongoURI = 'mongodb+srv://caman3874:qwertyuiopaman1234##amanco-pexfz.mongodb.net/test?retryWrites=true&w=majority';
const promise = mongoose.connect(mongoURI, { useNewUrlParser: true });
const conn = mongoose.connection;
let gfs;
conn.once('open',() => {
gfs = Grid(conn, mongoose.mongo);
gfs.collection('uploads');
});
//create storage object
const storage = new GridFsStorage({
db: promise,
file: (req, file) => {
return new Promise((resolve, reject) => {
crypto.randomBytes(16, (err, buf) => {
if (err) {
return reject(err);
}
const filename = buf.toString('hex') + path.extname(file.originalname);
const fileInfo = {
filename: filename,
bucketName: 'uploads'
};
resolve(fileInfo);
});
});
}
});
const upload = multer({ storage });
Hope this works!
Related
app.js
const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const mongoose = require('mongoose');
const app = express();
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', "ejs");
mongoose.set('strictQuery', false);
mongoose.connect("mongodb://localhost:27017/friendDB", { useNewUrlParser: true });
// Create Schema
const friendSchema = new mongoose.Schema({
email: String,
password: Array,
});
// Create Model through Schema
const Friend = new mongoose.model("Friend", friendSchema);
app.get('/', (req, res) => {
res.render("home");
})
app.get('/SignUp', (req, res) => {
res.render('SignUp');
})
app.get('/SignIn', (req, res) => {
res.render('SignIn');
});
app.get('/welcome', (req, res) => {
res.render('welcome');
})
// app.get("/signInFail", (req,res)=>{
// res.render("signInFail");
// });
app.post('/SignUp', (req, res) => {
// console.log(req.body.username);
// console.log(req.body.password);
const newFriend = new Friend({
email: req.body.username,
password: req.body.password,
confirmPassword: req.body.password
});
newFriend.save((err) => {
if (err) {
console.log(err);
} else {
res.render("welcome");
}
})
});
app.post('/SignIn', (req, res) => {
const username = req.body.username;
const password = req.body.password;
Friend.findOne({ email: username }, function (err, foundFriend) {
if (err) {
console.log(err);
} else {
if (foundFriend) {
if (foundFriend.password === password) {
res.render("welcome");
}
}
}
});
});
// app.post("/SignIn", (req,res)=>{
// const username = req.body.username;
// const password = req.body.password;
// Friend.findOne({email:username}, (err, foundFriend)=>{
// if(err){
// console.log(err);
// }else{
// if(foundFriend){
// if(foundFriend.password === password){
// res.render("welcome");
// }
// }
// }
// });
// });
app.listen(3000, () => {
console.log('server listening at port 3000');
})
welcome.ejs
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome</title>
<link rel="stylesheet" href="css/styles.css">
<!-- CSS only -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
</head>
<body class="text-center" style="margin:5% 35% 0 35%;">
<main class="form-signin w-100 m-auto">
<form>
<img src="./images/haikyyu main logo.png" alt="main_logo" height="150" width="150"
style="padding-bottom: 15px;border-radius: 100px;">
<h1 class="h3 mb-3 fw-normal">Hurray!</h1>
<h2>You've Signed In successfully😉.</h2>
<p class="mt-5 mb-3 text-muted">© 2022</p>
</form>
</main>
</body>
</html>
SignIn.ejs
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<title>SignIn</title>
</head>
<body>
<body class="text-center" style="margin:5% 35% 0 35%;">
<main class="form-signin w-100 m-auto">
<form action="/SignIn" method="post">
<img src="./images/haikyyu main logo.png" alt="main_logo" height="150" width="150"
style="padding-bottom: 15px;border-radius: 100px;">
<h1 class="h3 mb-3 fw-normal">Sign-In</h1>
<div class="form-floating">
<input type="email" class="form-control" id="floatingInput" placeholder="name#example.com" name="username">
<label for="floatingInput">Email address</label>
</div>
<div class="form-floating" style="padding-top: 3px;">
<input type="password" class="form-control" id="floatingPassword" placeholder="Password" name="password">
<label for="floatingPassword">Password</label>
</div>
<div class="checkbox mb-3" style="padding-top:15px">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<div class="buttons" style="display: flex; justify-content: space-between;">
Sign Up
<button class="w-50 btn btn-lg" type="submit"
style="margin-left: 15px;background-color: rgb(236, 76, 18);color:aliceblue;">Sign In</button>
</div>
<p class="mt-5 mb-3 text-muted">© 2022</p>
</form>
</main>
</body>
</body>
</html>
It's not showing any error, it was working when I first tried it but after some time, when I tried to sign in with the same username and password the loader is just keep loading not showing the welcome page.
I think there is some problem in this code:
app.post('/SignIn', (req, res) => {
const username = req.body.username;
const password = req.body.password;
Friend.findOne({ email: username }, function (err, foundFriend) {
if (err) {
console.log(err);
} else {
if (foundFriend) {
if (foundFriend.password === password) {
res.render("welcome");
}
}
}
});
});
But I'm unable to figure out what it is.
I am working on an Image Upload server using multer and mongodb following This GeeksForGeeks Post:
https://www.geeksforgeeks.org/upload-and-retrieve-image-on-mongodb-using-mongoose/
I did everything same as in this post but my localhost server is just loading and loading.
My Project Structure :
https://i.stack.imgur.com/p1NhC.png
App.js:
// Step 1 - set up express & mongoose
var express = require('express')
var app = express()
var bodyParser = require('body-parser');
var mongoose = require('mongoose')
var fs = require('fs');
var path = require('path');
require('dotenv/config');
// Step 2 - connect to the database
mongoose.connect(process.env.MONGO_URL,
{ useNewUrlParser: true, useUnifiedTopology: true }, err => {
console.log('connected')
});
// Step 3 - code was added to ./models.js
// Step 4 - set up EJS
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
// Set EJS as templating engine
app.set("view engine", "ejs");
// Step 5 - set up multer for storing uploaded files
var multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now())
}
});
var upload = multer({ storage: storage });
// Step 6 - load the mongoose model for Image
var imgModel = require('./model');
// Step 7 - the GET request handler that provides the HTML UI
app.get('/', (req, res) => {
imgModel.find({}, (err, items) => {
if (err) {
console.log(err);
res.status(500).send('An error occurred', err);
}
else {
res.render('imagesPage', { items: items });
}
});
});
// Step 8 - the POST handler for processing the uploaded file
app.post('/', upload.single('image'), (req, res, next) => {
var obj = {
name: req.body.name,
desc: req.body.desc,
img: {
data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
contentType: 'image/png'
}
}
imgModel.create(obj, (err, item) => {
if (err) {
console.log(err);
}
else {
// item.save();
res.redirect('/');
}
});
});
// Step 9 - configure the server's port
var port = process.env.PORT || '3000'
app.listen(port, err => {
if (err)
throw err
console.log('Server listening on port', port)
})
Model.js:
// Step 3 - this is the code for ./models.js
var mongoose = require('mongoose');
var imageSchema = new mongoose.Schema({
name: String,
desc: String,
img:
{
data: Buffer,
contentType: String
}
});
//Image is a model which has a schema imageSchema
module.exports = new mongoose.model('Image', imageSchema);
.env:
MONGO_URL = mongodb://localhost/mongo
PORT = 5500
imagesPage.ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Image Uploading</title>
</head>
<body>
<h1>To Upload Image on mongoDB</h1>
<hr>
<div>
<form action="/" method="POST" enctype="multipart/form-data">
<div>
<label for="name">Image Title</label>
<input type="text" id="name" placeholder="Name"
value="" name="name" required>
</div>
<div>
<label for="desc">Image Description</label>
<textarea id="desc" name="desc" value="" rows="2"
placeholder="Description" required>
</textarea>
</div>
<div>
<label for="image">Upload Image</label>
<input type="file" id="image"
name="image" value="" required>
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
<hr>
<h1>Uploaded Images</h1>
<div>
<% items.forEach(function(image) { %>
<div>
<div>
<img src="data:image/<%=image.img.contentType%>;base64,
<%=image.img.data.toString('base64')%>">
<div>
<h5><%= image.name %></h5>
<p><%= image.desc %></p>
</div>
</div>
</div>
<% }) %>
</div>
</body>
</html>
Please tell what i am doing wrong.
I very new to backend so I don't know what to do
Thanks
I'm trying to build a database using mongodb where it will render to an html page using ejs. Backend is node/express.
How do I link the button to an addeventlistener. EJS documentation is limited and I've read other posts that says ejs only renders html but no other functionality.
Eventually, I would like to use an async/await to link the js with the backend.
Here is my ejs:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<h1>The Beautiful Game</h1>
<form action="/players" method="POST">
<input type="text" placeholder="name" name="name" />
<input type="text" placeholder="club" name="club" />
<button type="submit" class='submitButton'>Submit</button>
</form>
<h2>Players</h2>
<ul class="players">
<% for (var i = 0; i < players.length; i++) {%>
<li class="players">
<span><%= players[i].name %></span>:
<span><%= players[i].club %></span>
<button class="dataDeleteNameButton" data-id="<%=players[i]._id%>">Delete</button> <!-- linking this button -->
</li>
<% } %>
</ul>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
Here is my js:
document
.querySelector("dataDeleteNameButton")
.addEventListener("click", deleteEntry);
async function deleteEntry() {
console.log("Button is working!");
}
Here is the server, if needed:
const express = require("express");
const bodyParser = require("body-parser");
const app = express();
const cors = require("cors");
const MongoClient = require("mongodb").MongoClient;
const PORT = process.env.PORT || 8000;
app.use(cors());
const username = "hidden";
const password = "hidden";
const connectionString = `mongodb+srv://${username}:${password}#cluster0.7k2ww.mongodb.net/myFirstDatabase?retryWrites=true&w=majority`;
MongoClient.connect(connectionString, { useUnifiedTopology: true })
.then((client) => {
console.log("Connected to database");
const db = client.db("soccer-players");
const playerCollection = db.collection("players");
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static("public"));
app.get("/", (req, res) => {
db.collection("players")
.find()
.toArray()
.then((result) => {
res.render("index.ejs", { players: result });
})
.catch((error) => console.error(error));
});
app.get("/api/players", (req, res) => {
db.collection("players")
.find()
.toArray((err, arr) => {
res.json(arr);
});
});
app.post("/players", (req, res) => {
playerCollection
.insertOne(req.body)
.then((result) => {
res.redirect("/");
})
.catch((error) => console.error(error));
console.log(req.body);
});
app.delete("/", (req, res) => {
// playerCollection.deleteOne() <--
// let findID =
});
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
})
.catch((error) => console.error(error));
Picture of what it looks like:
This is my script tag path: ../client-side-folder/js-folder/main.js
Directory:
main-folder
+--client-side-folder
+----js-folder
+------main.js
+--views-folder
+----index.ejs
You can just do onclick="myFunction(theIdOfTheButtonHere)"
Here is an example:
https://www.w3schools.com/jsref/event_onclick.asp
Here, there is middleware for uploading and storing image file. I have uploaded in mongoDB using mongoose library. Here I want to allow only docx file to upload and uploading other file type shows "Invalid filetype". How can I assign mimetype in such a way that it accepts only the docx file?
middleware.js
const util = require("util");
const multer = require("multer");
const GridFsStorage = require("multer-gridfs-storage");
const mongoose = require('mongoose');
const Grid = require('gridfs-stream');
const mongoURI ='mongodb://localhost:27017/file_uploaded';
const promise = mongoose.connect(mongoURI, { useNewUrlParser: true });
const conn = mongoose.connection;
let gfs;
conn.once('open',() => {
gfs = Grid(conn, mongoose.mongo);
gfs.collection('uploads');
});
var storage = new GridFsStorage({
db: promise,
options: {useNewUrlParser: true, useUnifiedTopology: true },
file: (req, file) => {
const match = ["image/png", "image/jpeg"];
if (match.indexOf(file.mimetype)===-1) {
const filename = `${Date.now()}-bezkoder-${file.originalname}`;
return filename;
}
return {
bucketName: "photos",
filename: `${Date.now()}-bezkoder-${file.originamname}`
};
}
});
var uploadFile = multer({storage: storage}).single("file");
var uploadFilesMiddleware = util.promisify(uploadFile);
module.exports = uploadFilesMiddleware;
upload.js
This is the controller for uploading image.
const upload = require("../middleware/middleware");
const uploadFile = async(req,res) => {
try {
await upload(req,res);
console.log(req.file);
if (req.file == undefined) {
return res.send('You must select a file');
}
return res.send('File has been uploaded.');
} catch(error) {
console.log(error);
return res.send(`Error when trying upload image: ${error}`);
}
};
module.exports = {
uploadFile: uploadFile
};
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Node.js upload images</title>
</head>
<body>
<h4>Node.js upload images - bezkoder.com</h4>
<form class="mt-4"
action="/upload"
method="POST"
enctype="multipart/form-data"
>
<div class="form-group">
<input
type="file"
name="file"
id="input-files"
class="form-control-file border"
/>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<hr />
</body>
</html>
If you want only specific file type. Check inside file option and reject error.
const express = require('express');
const multer = require('multer');
const GridFsStorage = require('multer-gridfs-storage');
const url = 'mongodb://localhost:27017/files';
const storage = new GridFsStorage({
url: url,
options: {useUnifiedTopology: true},
file: (req, file) => {
return new Promise((resolve, reject) => {
if (file.mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document') {
resolve({
bucketName: 'words'
})
} else {
reject(Error("File type has been rejected"));
}
});
}
});
const upload = multer({ storage });
const app = express();
app.get('/', (req, res, next) => {
res.sendFile(__dirname+"/index.html")
});
app.post('/file', upload.single('file'), (req, res, next) => {
res.send(req.file)
});
app.listen(3333);
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form enctype="multipart/form-data" action="/file" method="post">
<div>
<label>Select a file:</label>
<input type="file" name="file" />
</div>
<div>
<button type="submit">Submit</button>
</div>
</form>
</body>
I have a very simple form that is used to upload image file on the server's file system and render the image on the page. Apparent I can upload the image as expected but fail's to render the image. I get a broken image icon and
when I open the image location I get can't GET /uploads/undefined below is my code app.js, and index.ejs respectively
const express = require('express');
const multer = require('multer');
const ejs = require('ejs');
const path = require('path');
const port = 3000;
// Init app
const app = express()
// Set storage engine
const storage = multer.diskStorage({
destination: './public/uploads',
filename: function (req, file, cb) {
// null as first argument means no error
cb(null, Date.now() + '-' + file.originalname )
}
})
// Init upload
const upload = multer({
storage: storage,
limits: {
fileSize: 1000000
},
fileFilter: function (req, file, cb) {
sanitizeFile(file, cb);
}
}).single('files')
// Set view engine
app.set('view engine', 'ejs')
// Set static folder
app.use(express.static('./public'));
// Set the initial route
app.get('/', (req, res) => {
res.render('index');
})
// Handle the upload route
app.post('/upload', (req, res) => {
// res.send('done');
upload(req, res, (err) => {
if (err){
res.render('index', { msg: err})
}else{
// If file is not selected
if (req.file == undefined) {
res.render('index', { msg: 'No file selected!' })
}
else{
res.render('index', {
msg: 'File uploaded successfully!',
file: `uploads/${req.file.filname}`
});
}
}
})
})
function sanitizeFile(file, cb) {
// Define the allowed extension
let fileExts = ['png', 'jpg', 'jpeg', 'gif']
// Check allowed extensions
let isAllowedExt = fileExts.includes(file.originalname.split('.')[1].toLowerCase());
// Mime type must be an image
let isAllowedMimeType = file.mimetype.startsWith("image/")
if (isAllowedExt && isAllowedMimeType) {
return cb(null, true) // no errors
}
else {
// pass error msg to callback, which can be displaye in frontend
cb('Error: File type not allowed!')
}
}
app.listen(port, () => console.log('Server started at port : ' + port))
my index.ejs
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
<title>Image Upload Demo</title>
</head>
<body>
<div class="container">
<h1>Image Upload</h1>
<%= typeof msg != 'undefined' ? msg : '' %>
<form method="POST" action="/upload" enctype="multipart/form-data">
<div class="file-field input-field">
<div class="btn grey">
<span>File</span>
<input name="files" type="file">
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text">
</div>
</div>
<button type="submit" class="btn">Submit</button>
</form>
<br>
<img src="<%= typeof file != 'undefined' ? file : '' %>"class="img-responsive">
</div>
<script src="https://code.jquery.com/jquery-3.4.1.min.js" integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
</body>
</html>
You were so close! You just made a typo - req.file.filname should be req.file.filename in your upload handler.