Show Image file using NodeJS - node.js

Using node.js and mongodb I want to upload image and show that image using it's id.
but When i run it, showing an error..
Error: Failed to lookup view "/showImage" in views directory "H:\NodeJS\AddImage
\views"
searching a lot but couldn't find any proper and working solution for me.
what's the problem??
can anyone help??
thanks..
here is my code...........
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var path = require('path');
var multer = require('multer');
app.use(bodyParser.json());
app.use(express.static('public'));
var imagefile = require('./routes/imagefile');
app.set('view engine', 'ejs');
mongoose.connect('mongodb:..url');
imagefile(app);
app.listen(3000);
console.log('Running on port 3000');
imagefile.js
var express = require('express');
var multer = require('multer');
var mongoose = require('mongoose');
var fs = require('fs');
var imageSchema = mongoose.Schema({
img: { data: Buffer, contentType: String },
imageName : String
});
var Item = mongoose.model('Clothes',imageSchema);
var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'public/')
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
});
var upload = multer({
storage: storage
});
module.exports = function (app) {
app.get('/', function(req, res, next) {
res.render('index.ejs');
});
app.get('/images/:id', function(req, res) {
Item.findById(req.params.id, function (error, result) {
//res.contentType(result.contentType);
console.log(result.imageName);
//res.end(result.image.buffer, "binary");
res.render('/showImage',{imageName : result.imageName, imageId : result.imageName});
});
});
app.post('/', upload.any(), function(req, res, next) {
var newItem = new Item();
newItem.img.data = fs.readFileSync(req.files[0].path)
newItem.img.contentType = 'image/png';
newItem.imageName = req.files[0].originalname;
newItem.save();
res.render('index.ejs');
});
};
index.ejs
<html>
<head>
<title>test</title>
</head>
<body>
<form action "/" method="POST" enctype="multipart/form-data">
<input type="file" name="myimage" ></input>
<input type="submit" name="submit" value="submit"></input>
</form>
</body>
</html>
showImage.ejs
<html>
<head>
<title>test</title>
</head>
<body>
<h1><%= imageName %></h1>
<h1><%= imageId %></h1>
<div class="header">
<img src='/public/36417514_2140268509321308_7450232816341614592_n.jpg %>' />
</div>
</body>
</html>

Remove the leading slash in this function:
app.get('/images/:id', function(req, res) {
// Rest of the code
// ...
res.render('showImage', // <-- Remove slash
{imageName : result.imageName, imageId : result.imageName});
});
});
the problem is that it looks for file named '/showImage.ejs'.

Related

Getting TypeError: Cannot read property 'content-length' of undefined When Using Node.js Formidable

I'm trying to console.log a number I type in an input using formidable. I am getting an error that says TypeError: Cannot read property 'content-length' of undefined. I have tried to add a fs.readFile into the code and it won't work.
Here is my app.js
const express = require('express');
const http = require('http');
const formidable = require('formidable');
const fs = require('fs');
const ejs = require('ejs');
const path = require('path');
const multer = require('multer');
const upload = multer({ dest: 'upload/'});
const type = upload.fields([{ name: 'gradeNumber', maxCount: 10 }]);
const app = express();
app.use(express.static(__dirname + '/public'));
app.set('view engine', 'ejs');
app.get('/fileupload', function (req, res) {
res.render("upload")
});
app.post('/fileupload', function (req, res) {
const form = new formidable.IncomingForm();
form.parse(function (err, fields, files) {
console.log(fields.gradeNumber);
const oldpath = files.filetoupload.path;
const newpath = 'C:/Users/Shubh Computer/Desktop/VSCode/Grades/1/' + files.filetoupload.name;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
});
});
app.listen(3000);
upload.ejs
<!DOCTYPE html>
<html>
<head>
<title>Upload File</title>
</head>
<body>
<form action="fileupload" method="post" enctype="multipart/form-data">
<input type="file" name="filetoupload"><br>
<label>What Grade</label><input type="text" name="gradeNumber"><br>
<input type="submit">
</form>
</body>
</html>
I'm trying to log the input with the name "gradeNumber". If somebody could help me I will be very grateful because I've gotten very frustrated with this.
"req" parameter in form.parse() method is omitted.
(method) IncomingForm.parse(req: IncomingMessage, callback?: (err: any, fields: Fields, files: Files) => any): void
Try changing the code as below.
app.post('/fileupload', function (req, res) {
const form = new formidable.IncomingForm();
form.parse(req, function (err, fields, files) {
console.log(fields.gradeNumber);
const oldpath = files.filetoupload.path;
const newpath = 'C:/Users/Shubh Computer/Desktop/VSCode/Grades/1/' + files.filetoupload.name;
fs.rename(oldpath, newpath, function (err) {
if (err) throw err;
res.write('File uploaded and moved!');
res.end();
});
});
});

Simple To-Do app just doesn't print to-dos

I am building a simple To Do application Using node js, express, mongodb and ejs.
My get Route renders the form and the post route handles post request on the form, they both work perfect, any time I insert a (todo) it gets saved and can be found in my Mongo compass.
But it does not appear on the screen as Todo App should be. It only prints out usual bullets of (ul). I don't know what I am doing wrong, here is my code:
const express = require('express');
const app = express();
const port = 8080;
const bodyParser = require('body-parser');
const multer = require('multer');
const upload = multer();
const session = require('express-session');
const cookieParser = require('cookie-parser');
const mongoose = require('mongoose');
mongoose.connect("mongodb://localhost/Todo-App",
{useUnifiedTopology:true,useNewUrlParser:true,useFindAndModify:false,useCreateIndex:true});
app.set('view engine','ejs');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(upload.array());
app.use(cookieParser());
app.use(session({secret:"secret"}));
var todoschema = mongoose.Schema({
item:String,
});
var Todo = mongoose.model("Todo",todoschema);
app.get('/',(req,res)=>{
res.render('home.ejs',{Todo:Todo});
});
app.post('/',(req,res)=>{
var newTodo = new Todo({
item:req.body.item,
});
newTodo.save((err,result)=>{
if(err){
throw err;
}
else{
res.redirect('/');
}
})
})
app.listen(8080,()=>{
console.log("App is running...")
})
Here is my code in the ejs file
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<h1>My To-Do Application</h1>
<form action="/" method="post">
<input type="text" name="item" placeholder="Enter Item">
<input type="submit" value="Add To List">
</form>
<%for(var i = 0; i < Todo.length; i++){%>
<li> <%=Todo[i]%></li>
<%}%>
</body>
</html>
I think the issue is here
app.get('/', (req, res) => {
res.render('home.ejs', { Todo : Todo });
});
you are doing the res.render without finding the documents from db
I think we need to add a find query before doing res.render
it should be something like that
app.get('/', (req, res) => {
Todo.find({}, (err, todos) => { // passing an empty object as a first argument to the find method means we need to get all the documents from Todo collection
if (err) {
throw err;
} else {
res.render('home.ejs', { Todo: todos });
}
});
});
hope it helps

Multer is not populating req.body and req.file

I am using Multer to parse a multipart form in a keystone environment and and not able to access the req.body and req.file data inside my route controller
routes/index.js
var keystone = require('keystone'),
middleware = require('./middleware');
var bodyParser = require('body-parser');
//multi-part form parser for FTP api
var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({storage: storage});
exports = module.exports = function(app) {
app.use(bodyParser.json({limit: '10mb'}));
app.use(bodyParser.urlencoded({limit: '10mb', extended: true}));
app.post('/upload_api', upload.single('formFile'), routes.api.uploadFTP);
};
routes/api/uploadFTP.js
var keystone = require('keystone');
var ftpMod = require('ftp');
var fs = require('fs');
exports = module.exports = function(req, res) {
console.log("req.body is ");
console.log(req.body);
console.log("req.file is ");
console.log(req.file);
res.send("console.log() outputted to screen");
}
public/test-upload.html
<html>
<body>
<form name="sampleForm" enctype="multipart/form-data" action="/upload_api" method="post">
<p>Method</p>
<input type="text" name="method"><br>
<p>Options</p>
<input type="text" name="options"><br>
<p>File</p>
<input type="file" name="formFile"><br><br>
<input type="submit" value="Click to Send">
</form>
</body>
</html>
The response i receive from nodejs is
>req.body is
{}
req.file is
undefined
I am expecting req.body to contain {method: "sometext"}
and req.file to be populated
You can not get values in either req.body or req.file. Replace youe uploadFTP.js with below given code.
var multer = require('multer');
var path = require('path');
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, <<path where you want to store your files>>);
},
filename: function(req, file, callback) {
callback(null, path.basename(Date.now() + '_' + file.originalname));
},
});
var maxSize = 1024 * 1024;
var upload = multer({
storage: storage,
fileFilter: function(req, file, callback) {
var ext = path.extname(file.originalname);
if(ext !== '.gif' && ext !== '.jpeg') {
return callback(res.status(202).end();, null);
}
callback(null, true);
},
limits: {fileSize: maxSize},
}).single('image');
exports = module.exports = function (req, res) {
upload(req, res, function(err) {
console.log(storage.diskStorage);
if(err) {
return res.status(201).end();
}
//Do stuff here
res.status(200).end();
});
}
Replace below line in index.js
app.post('/upload_api', upload.single('formFile'), routes.api.uploadFTP);
with
app.post('/upload_api', routes.api.uploadFTP);

Error uploading files using Multer in NodeJs

I am trying to write an Express-based API for uploading files. The filename and directory path should be set dynamically.
My code:
var crypto = require('crypto')
var express = require('express');
var fs = require('fs');
var mime = require('mime');
var mkdirp = require('mkdirp');
var multer = require('multer');
var app = express();
var path = './uploads';
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, path);
console.log('Im in storage destination'+path);
},
filename: function (req, file, callback) {
console.log('Im in storage filename'+path);
//callback(null, file.fieldname + '-' + Date.now());
crypto.pseudoRandomBytes(16, function (err, raw) {
callback(null, Date.now() + '.' + mime.extension(file.mimetype));
});
}
});
var upload = multer({ storage : storage}).single('userPhoto');
app.post('/photo',function(req,res){
path += '/pics/shanmu/';
console.log('Im in post , outside upload'+path);
upload(req,res,function(err) {
console.log('Im in post , inside upload'+path);
if(err) {
return res.end('Error uploading file.');
}
res.end('File is uploaded'+path);
console.log('File is uploaded'+path);
});
});
app.listen(3000,function(){
console.log('Working on port 3000');
});
My folder structure:
When I run the code, the file should be uploaded in the uploads/ folder. (This folder has two nested folders inside it - uploads/pics/shanmu).
When I triggered it from postman, it only works once. When I try the second time, I cannot upload files.
Please advise.
Working on sometime I got a solution using multer module.Using this module you can upload both files and images.And it successfully uploaded to the destination folder.
Here is my server code app.js
var express =r equire('express');
var multer = require('multer');
var path = require('path')
var app = express();
var ejs = require('ejs')
app.set('view engine', 'ejs')
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads')//here you can place your destination path
},
filename: function(req, file, callback) {
callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname))
}
})
app.get('/api/file',function(req,res){
res.render('index');
});
app.post('/api/file', function(req, res) {
var upload = multer({
storage: storage}).single('userFile');
upload(req, res, function(err) {
console.log("File uploaded");
res.end('File is uploaded')
})
})
app.listen(3000,function(){
console.log("working on port 3000");
});
Create a views folder and place this index.ejs file in it
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form id="uploadForm" enctype="multipart/form-data" method="post">
<input type="file" name="userFile" />
<input type="submit" value="Upload File" name="submit">
</form>
</body>
</html>
After this run the server as node app.js.Open the browser and type http://localhost:3000/api/file after runnig this url choose a file which you want to upload to destination folder.And have a successfull response in both terminal and browser.Hope this helps for you.
I got your code working. See:
https://gist.github.com/lmiller1990/3f1756efc07e09eb4f44e20fdfce30a4
I think the problem was with the way you declared destination. I'm not sure why, though. I got it working by just passing the path as a string.
Best of luck!

Nodejs + Expressjs : Pass value in POST with Uploading of file

I am new in node. I just want to pass value in POST request with something like uploading of file. here is my sample code:
var express = require('express');
var app = express();
var fs = require("fs");
var bodyParser = require('body-parser');
var urlencodedParser = bodyParser.urlencoded({ extended: false });
var multer = require('multer');
var upload = multer({ dest: '/tmp/'});
app.use(express.static('public'));
app.post('/process_post', urlencodedParser, function (req, res) {
console.log(req.files.file.name);
var file = __dirname + "/" + req.files.file.name;
fs.readFile( req.files.file.path, function (err, data) {
fs.writeFile(file, data, function (err) {
if( err ){
console.log( err );
}else{
response = {
message:'Save successfully',
first_name:req.body.firstname,
last_name:req.body.lastname,
filename:req.files.file.name
};
}
console.log( response );
res.end( JSON.stringify( response ) );
});
});
})
HTML:
<html>
<body>
<form action="http://127.0.0.1:8081/process_post" method="POST" enctype="multipart/form-data">
First Name: <input type="text" name="firstname">
<br>
Last Name: <input type="text" name="lastname">
<br>
Picture: <input type="file" name="file" size="50" />
<br>
<input type="submit" value="Submit">
</form>
</body></html>
The req.files is always undefine.
Thanks in advance!
You're requireing multer, but never configuring or using it. from the docs:
var multer = require('multer')
var upload = multer({ dest: 'uploads/' })
app.post('/photos/upload', upload.array('photos', 12), function (req, res, next) {
// req.files is array of `photos` files
// req.body will contain the text fields, if there were any
})

Resources