File download is not working with nodejs gridfs - node.js

i'm uploading images to gridfs-stream using node and express..uploading is working fine but am unable to download
app.post('/upload', function (req, res) {
var tempfile = req.files.displayImage.path;
var origname = req.files.displayImage.name;
var _id = guid();
var writestream = gfs.createWriteStream({
filename: _id
});
// open a stream to the temporary file created by Express...
fs.createReadStream(tempfile)
.on('end', function () {
res.send(_id);
})
.on('error', function () {
res.send('ERR');
})
// and pipe it to gfs
.pipe(writestream);
});
app.get('/download', function (req, res) {
// TODO: set proper mime type + filename, handle errors, etc...
gfs
// create a read stream from gfs...
.createReadStream({
filename: req.param('filename')
})
// and pipe it to Express' response
.pipe(res);
});
the above code is unable to download the image by this cmd download?filename=acf58ae4-c853-f9f3-5c66-c395b663298a

You might need to check your values in params. But hopefully this near minimal sample provides some help:
Update
And it has helped, because it highlights that you are looking up the _id as a filename. Instead you should be doing this:
.createReadStream({
_id: req.param('filename')
})
if not
.createReadStream({
_id: mongoose.Types.ObjectId(req.param('filename'))
})
Since the _id field is different to the filename
app.js
var express = require('express');
var routes = require('./routes');
var http = require('http');
var path = require('path');
var app = express();
var mongoose = require('mongoose');
var Grid = require('gridfs-stream');
Grid.mongo = mongoose.mongo;
var conn = mongoose.createConnection('mongodb://localhost/mytest');
conn.once('open', function() {
console.log('opened connection');
gfs = Grid(conn.db);
// all environments
app.set('port', process.env.PORT || 3000);
app.use(express.logger('dev'));
app.use(app.router);
// development only
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
app.get('/', routes.index);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
});
routes/index.js
exports.index = function(req, res){
res.set('Content-Type', 'image/jpeg');
gfs.createReadStream({
filename: 'receptor.jpg'
}).pipe(res);
};

Related

Sample Hello World Express App is returning binary data

The following doesnt seem to work. It's simple Express sample code. You can ignore the other responses. Im just trying to get the basic '/' home page working and that's refusing to work. Code is as follows:
var express = require('express');
var sR = require('./routes/index');
var path = require('path');
var urlencoded = require('url');
var bodyParser = require('body-parser');
var json = require('json');
var methodOverride = require('method-override');
var jade = require('jade');
var fs = require('fs');
var http = require('http2');
const cookieParser = require('cookie-parser');
const logger = require('morgan');
const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');
const dbLoc = 'mongodb://localhost:27017';
const dbName = 'gothamDB';
var dbConn = null;
const dbURL = "mongodb://gotthamUser:abcd1234#localhost:27017/gothamDB"
const mongoClient = new MongoClient(dbURL, { useNewUrlParser: true, useUnifiedTopology: true});
// Use connect method to connect to the server
dbConn = mongoClient.connect(function(err, client) {
assert.strictEqual(null, err);
console.log("Connected successfully to server");
dbConn = client;
});
var app = express();
app.set('port', 8080);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', jade);
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.set('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});
app.post('/create_collection', function(req, res){
var db = dbConn.db('gothamDB');
var userData = db.createCollection(req.body.coll_name, function(err){
if(err){
res.send('Error creating database: ' + req.body.coll_name);
return;
}
res.send('Database ' + req.body.dbname + ' created successfully');
});
});
app.post('/new_contact', function(req, res){
var name = req.body.name;
var phone = req.body.phone;
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
collection.insert(
{name : name, phone: phone}
, function(err, result) {
assert.strictEqual(err, null);
assert.strictEqual(1, result.result.n);
assert.strictEqual(1, result.ops.length);
res.send("Inserted new record into the collection");
});
});
app.post('view_contact', function(req, res){
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
coll.find({'phone' : req.body.phone}).toArray(function(err, docs){
if(err) {
res.send("Error looking up the data");
return;
}
res.send(docs);
return;
});
});
app.post('delete_contact', function(req, res){
var db = dbConn.db('gothamDB');
var coll = db.collection(req.body.coll_name);
coll.deleteOne({'phone' : req.body.phone}).toArray(function(err, docs){
if(err) {
res.send("Error looking up the data");
return;
}
res.send(docs);
return;
});
});
//const key = path.join(__dirname + '/security/server.key');
//const cert = path.join(__dirname + '/security/server.crt');
const options = {
key: fs.readFileSync(__dirname + '/security/server.key'),
cert: fs.readFileSync(__dirname + '/security/server.crt')
}
http.createServer(app).listen(app.get('port'), function(err){
console.log('Express server lisetning on port ' + app.get('port'));
})
console.log("Server started");
Any clue? Browser shows as follows:
Itt's showing an ERR_INVALID_HTTP_RESPONSE
if I run a curl command, it shows the following:
NodeExample % curl -X GET 'http://localhost:8080/'
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file
If I put a breakpoint at the line:
res.send("Hello World");
that never hits. I've also tried putting in
res.header("Content-Type", "application/json");
but since the breakpoint never hits, it is not going to help I guess.
You are using set here
app.set('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});
It should be get
app.get('/', function(req, res){
res.send("Hello World");
res.end();
console.log("Hello World sent");
});

app post is not working i am not getting the output

var express = require("express");
var app = express();
var bodyParser = require('body-parser');
var port = 3000;
const fs = require('fs');
// we are connecting to the mangodb using mangoose
var mongoose = require("mongoose");
// Now we are using bodyParser
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
mongoose.connect("mongodb://localhost:27017/YourDB", { useNewUrlParser: true })
// now we are creating the schema to the database
var nameSchema = new mongoose.Schema({
firstName: String,
lastNameName: String
});
// Now we have to create a model
var User = mongoose.model("User", nameSchema);
app.use("/", (req, res) => {
res.sendFile(__dirname + "/index.html");
});
// Now we are posting the data
app.post("/addname", (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
myData.save()
console.log(myData);
fs.writeFile(__dirname +"/data.json",myData, function(err){
if(err) {
return console.log(err);
}
console.log("The file is saved ");
})
console.log(myData)
})
// Now we are getting the data
app.listen(port, () => {
console.log("Server listening on port " + port);
});
1)I am using express app.post to post the data into database and store the data into the write file to check
2) app.post is not working it tried console.log to check but it is not going inside the function
3) I am not getting output as well as any error plese help me
there is no error handling and response handling in this code.
it will be readable if we write post method with async/await :
app.post("/addname", async (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
await myData.save()
console.log(myData);
fs.writeFileSync(__dirname +"/data.json", myData)
console.log(myData)
})
you will add next() to app.use
var User = mongoose.model("User", nameSchema);
app.use("/", (req, res,next) => {
res.sendFile(__dirname + "/index.html");
next()
});
// Now we are posting the data
app.post("/addname", (req, res) => {
console.log("nnnnnn")
console.log(req.body.firstName)
var myData = new User(req.body);
myData.save()
console.log(myData);
fs.writeFile(__dirname +"/data.json",myData, function(err){
if(err) {
return console.log(err);
}
console.log("The file is saved ");
})
console.log(myData)
})
// Now we are getting the data
app.listen(port, () => {
console.log("Server listening on port " + port);
});
That's because every request is going to this app.use code block. app.use("/", (req, res) => { ... });
Just Put it below the app.post("/addname", (req, res) => { ... });
app.use is used to mount middlewares into the request-response chain. So, every request that comes matches the /(which is essentially every request) goes inside that middleware. So, use your routes first then use the middleware at the end.
EDIT:
Let me give you a mcve which I tested locally:
const express = require('express');
const fakeData = function(){
return {
s: "fakeData"
}
}
const app = express();
const port = 8181
const path = require('path')
app.get("/a", (req, res) => {
return res.json({d:'yay'});
});
app.use('/',(req,res)=>{
return res.json(fakeData());
})
app.listen(port, () => {
console.log(`Server started on PORT ${port}`);
});
Because every request goes through a mounted middleware, so when you GET/POST/ANYTHING to localhost:8181/<abosulutely_any_path> it will go through the app.use because it treats that function as middleware and will return { s: "fakeData" }.
But when you make a GET call http://localhost:8181/a it will go to the app.get route BECAUSE WE DECLARED IT FIRST and return { d : "yay" }

Node JS Stream Only works on first iteration

I have a simple node app that parses a csv file into a string. In my server file, I call a module that runs makes a stream and pipes it into my parser.
The problem is that is code works perfectly the first time it is run, but fails after that. I've gotten a "Write after End" error so I believe there is something wrong with the stream or parser variable not being reset properly after each use. Thanks for any help!
const express = require('express');
const app = express();
const path = require('path');
const port = process.env.PORT || 3000;
const formidable = require('formidable');
const parser = require('./csvparse.js');
const fs = require('fs');
//send the index page on a get request
app.listen(port, () => console.log('Example app listening on port: ' + port));
app.get('*', (req, res) => res.sendFile(path.join(__dirname + "/index.html")));
app.post('/upload', function(req, res) {
//upload the file from the html form
var form = new formidable.IncomingForm();
form.parse(req,function(err, fields, files) {
if (err) throw err;
//get the path to the uploaded file for the parser to use
var filePath = files.spinFile.path;
parser(filePath, function(data) {
if (data == null) {
res.sendFile(path.join(__dirname + "/index.html"));
}
res.send("<code>" + data + "</code>");
});
});
});
The module export function looks like this:
module.exports = function(filePath, cb) {
var stream = fs.createReadStream(filePath);
stream.pipe(parser);
//when the stream is done, songsLog is complete and ready to be returned
stream.on('close', function() {
cb(songsLog);
});
};
Try wrapping the contents of your module.exports in another function.
module.exports = function(filepath, cb) {
function parse(filepath) {
const stream = fs.createReadStream(filepath)
etc...
}
return {
parse
}
}
then from your route, call parser.parse('file.txt') and you should have a new read stream.

Getting all the images uploaded from MongoDB

I made a upload image to a document and saved the path to the MongoDB , While retrieving the Image, It is showing only the current image which is being uploaded. I want to show all the images which is uploaded to the database. Please help me to display all the images from the Data base.
Thank you in advance :)
var express = require('express'); //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path'); //used for file path
var fs = require('fs-extra'); //File System - for file manipulation
var mongoose = require('mongoose');
var handlebars = require('handlebars');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine', 'hbs');
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(__dirname + '/public'));
//You can import your schema like this
const Name = require('./name');
app.get('/', function(req, res, next) {
res.render('index',{'title': 'New post app'});
});
//I have changed your route since it seems to be clashing with the above
app.post('/save' ,function (req, res, next) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('file', function(fieldname, file, filename, done){
console.log("Uploading" + filename);
//path where the file is being uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
var dirname = path.join( 'uploads/' + filename);
file.pipe(fstream);
fstream.on('close', function(){
console.log("Upload Success" + filename);
let name = new Name({
path: dirname
});
name.save((err)=>{
if(err) throw err;
console.log(`saved : ${name}`);
res.redirect('/profile');
call(dirname);
});
});
});
});
function call(dirname){
Name.findOne({path: dirname}, (err, result) =>{
if(err) throw err;
var imgpath = result.path;
console.log("Saved check" + imgpath);
app.get('/profile', (req, res) =>{
res.render('profile',{
photo: req.result,
result : imgpath
});
});
});
}
var server = app.listen(3030, function() {
console.log('Listening on port %d', server.address().port);
});
My name.js file Mongoose Schema
let mongoose = require('mongoose');
let Schema = mongoose.Schema;
let compileSchema = new Schema({
path: String
});
let Compile = mongoose.model('Compiles', compileSchema);
module.exports = Compile;
Views File to display the image
<html>
<head>
<title>User Profile</title>
</head>
<body>
<h1>Welcome</h1>{{result}}<br><br>
<img src="{{result}}" height="180" width="250">
</body>
</html>
You are using findOne which only retrieves one object from the database. So if you want to retrieve all the images your code should be something like this :
var express = require('express') // Express Web Server
var busboy = require('connect-busboy') // middleware for form/file upload
var path = require('path') // used for file path
var fs = require('fs-extra'); // File System - for file manipulation
var mongoose = require('mongoose')
var handlebars = require('handlebars')
var mongoClient = require('mongodb').mongoClient
var objectId = require('mongodb').ObjectId
var app = express()
app.use(busboy())
app.use(express.static(path.join(__dirname, 'public')))
mongoose.Promise = global.Promise
mongoose.connect('mongodb://localhost:27017/postname')
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4 Route definition
============================================================ */
app.set('view engine', 'hbs')
app.set('views', path.join(__dirname, 'views'))
app.use(express.static(__dirname + '/public'))
// You can import your schema like this
const Name = require('./name')
app.get('/', function (req, res, next) {
res.render('index', {'title': 'New post app'})
})
// I have changed your route since it seems to be clashing with the above
app.post('/save' , function (req, res, next) {
var fstream
req.pipe(req.busboy)
req.busboy.on('file', function (fieldname, file, filename, done) {
console.log('Uploading' + filename)
// path where the file is being uploaded
fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename)
var dirname = path.join( 'uploads/' + filename)
file.pipe(fstream)
fstream.on('close', function () {
console.log('Upload Success' + filename)
let name = new Name({
path: dirname
})
name.save((err) => {
if (err) throw err
console.log(`saved : ${name}`)
res.redirect('/profile')
// removed call(), no need for it
})
})
})
})
app.get('/profile', (req, res) => {
// get all documents in the db by using find with no conditions
Name.find({}, (err, results) => {
if (err) throw err
var images = []
for (var result of results) {
images.push(result.path)
}
res.render('profile', {
images: images
})
})
})
var server = app.listen(3030, function () {
console.log('Listening on port %d', server.address().port)
})
And in the views you should loop through the images to display them, i believe you are using handlebars so the view should be something like this :
<html>
<head>
<title>User Profile</title>
</head>
<body>
<h1>Welcome</h1>
{{#each images}}
<img src="{{this}}" height="180" width="250">
{{/each}}
</body>
</html>

Mongodb Insert data API no respone

I need an API to insert data from android to mongodb , I follow this ,the code can run , have NO error , and I use POSTMAN try to post some data , it always say could not get any respone , seem to have an error connecting to 192.168.1.105:3000/songs
but I can use find all api and findByID.
This took me hours , please help , so depress :(
app.js
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
songs = require('./routes/route');
var jsonParser = bodyParser.json();
app.post('/songs', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400);
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.get('/songs',songs.findAll);
app.get('/findById/:id',songs.findById);
app.get('/songs',songs.addSong);
route
var mongoose = require('mongoose');
var mongo = require('mongodb');
var uri = "mongodb://XXXX:XXXX#ds061365.mongolab.com:61365/aweitest";
mongoose.connect(uri);
// we're connected!
var db = mongoose.connection.db;
var BSON = require('bson').BSONPure;
var body = require('body-parser');
db.on('error', console.error.bind(console, 'connection errrrrrrrror:'));
db.once('open', function() {
console.log("mongodb is connected!!");
});
exports.findAll = function(req, res) {
db.collection('songs',function(err, collection) {
collection.find().toArray(function(err, items) {
res.send(items);
});
});
};
exports.findById = function(req, res) {
var id = req.params.id;
console.log('Retrieving song: ' + id);
db.collection('songs', function(err, collection)
collection.findOne({'_id':new BSON.ObjectID(id)}, function(err, item) {
res.send(item);
});
});
};
exports.addSong = function(req, res) {
var song = req.query;
console.log('Adding song: ' + JSON.stringify(song));
db.collection('songs', function(err, collection) {
collection.insert(song, {safe:true}, function(err, result) {
{console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
};
Okay so I changed a few things in your code. I'm successfully getting the request body in the app.js file. Do have a look at the code.
route.js
var mongoose = require('mongoose');
var mongo = require('mongodb');
var uri = "mongodb://localhost:27017/test";
mongoose.connect(uri);
// we're connected!
var db = mongoose.connection.db;
var BSON = require('bson').BSONPure;
var body = require('body-parser');
db.on('error', console.error.bind(console, 'connection errrrrrrrror:'));
//db = mongoose.connection.db;
db.once('open', function() {
console.log("mongodb is connected!!");
});
exports.addSong = function(req, res) {
var song = req.body;
console.log('Adding song: ' + JSON.stringify(song));
db.collection('songs', function(err, collection) {
collection.insert(song, {safe:true}, function(err, result) {
if (err) {
res.send({'error':'An error has occurred'});
} else {
console.log('Success: ' + JSON.stringify(result[0]));
res.send(result[0]);
}
});
});
}
Notice that I have changed the URI to localhost, so change it again to the one you specified.
app.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json()); // support json encoded bodies
app.use(bodyParser.urlencoded({ extended: true })); // support encoded bodies
songs = require('./routes/route');
app.post('/songs', function(req, res) {
console.log("Request.Body : " + JSON.stringify(req.body));
if (!req.body) return res.sendStatus(400);
songs.addSong(req, res);
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
app.get('/songs',songs.addSong);
Since your only problem was that you weren't able to get the request body. You'll be able to get it with this code.
Also since your app.get('/songs',songs.addSong); is of type GET, you'll not be able to send POST Data through it. So change it to
app.post('/songs',songs.addSong);
Hope this helps.

Resources