One of the modules in our project is to upload an image from a webpage to mongo database using nodejs. We have completed connecting to a mongo database and upload an image using physical location of the image on the system, but we are not able to make the upload dynamic from a webpage.
We convert the image to a base64 code and then save it to the database. MongoDB returns a unique id. We want to integrate this process and make it dynamic. The code we used to connect to mongoDB and upload an image from physical location is available here.
var MongoClient = require('mongodb').MongoClient,
format = require('util').format,
fs = require('fs'),
http = require('http');
http.createServer(function (req, res) {
//should be triggered by the user upload button
put();
//triggered after the upload/button click
res.writeHead(200, {'Content-Type': 'text/html'});
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test_insert');
collection.find().toArray(function(err, results) {
//console.dir(results);
// Let's close the db
//ret = results[0];
console.log(results[0]);
res.end('<img alt="sample" src="data:image/png;base64,' + results[0].image + '">');
db.close();
});
});
//res.end("Hello World\n");
}).listen(3030);
function read() {
var image_base64 = fs.readFileSync('./uploads/2088-1nqsb3l.jpg').toString('base64');
return image_base64;
//console.log(base64_data);
}
function put() {
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test_insert');
collection.insert({image: read()}, function(err, docs) {
console.log("data inserted");
db.close();
});
});
}
function get() {
var ret;
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test_insert');
collection.find().toArray(function(err, results) {
//console.dir(results);
// Let's close the db
ret = results[0];
db.close();
});
});
return ret;
}
/*
MongoClient.connect('mongodb://127.0.0.1:27017/test', function(err, db) {
if(err) throw err;
var collection = db.collection('test_insert');
collection.insert({a: base64_data}, function(err, docs) {
collection.count(function(err, count) {
console.log(format("count = %s", count));
});
// Locate all the entries using find
collection.find().toArray(function(err, results) {
console.dir(results);
// Let's close the db
db.close();
});
});
});
*/
You have to send the image via XMLHttpRequest from the client to nodejs. Then store it in mongo like you did with the file, you read by fs.readFileSync.
Related
I'm trying to add a delete image functionality to my website and even though my code deletes the file from the images folder and removes the image record from my database, I get an error in the console and I don't get redirected to my home page. The error is :
DeprecationWarning: Calling an asynchronous function without callback is deprecated.
And my code:
var express = require('express');
var router = express.Router();
var db = require('../helpers/db');
var fs = require('fs');
router.post('/', function(req, res, next) {
if (req.method == 'POST') {
var id = req.body.id;
var path = req.body.path;
var author = req.body.author;
var completePath = 'public/images/uploads/' + path;
db.query('DELETE FROM image WHERE id = ?', [id], function(error, results, fields) {
if (error) throw error;
if (fs.unlink(completePath)) {
console.log('Successful');
res.redirect('/');
} else {
console.log('Unsuccessful');
}
})
}
});
module.exports = router;
My console logs Unsuccessful and it doesn't redirect me to res.redirect('/');
fs.unlink is an asynchronous function that takes a callback on success. You should use it like this:
db.query('DELETE FROM image WHERE id = ?', [id], function(error, results, fields) {
if (error) throw error;
fs.unlink(completePath,function(err) {
if(err) {
console.log('unsuccessful');
return;
}
console.log('successful');
res.redirect('/');
});
})
Can i use returning promise in socket.io "socket.on"? Like the following code.
socket.on('news', function (data) {
return News.findOne({id: data.id})
.then((news) => {
socket.emit('event', data.body);
return news;
})
});
In your socket.io server side part of your code you could use the node module 'node-mongodb-native' which in its documentation section shows you how to save something to your mongoDB instance like this:
var MongoClient = require('mongodb').MongoClient, assert = require('assert');
// Connection URL
var url = 'mongodb://localhost:27017/myproject';
// Use connect method to connect to the Server
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
console.log("Connected correctly to server");
// Insert a single document
db.collection('inserts').insertOne({a:1}, function(err, r) {
assert.equal(null, err);
assert.equal(1, r.insertedCount);
// Insert multiple documents
db.collection('inserts').insertMany([{a:2}, {a:3}], function(err, r) {
assert.equal(null, err);
assert.equal(2, r.insertedCount);
db.close();
});
});
});
I wanna take the whole list of notifies from mongo db but it returns empty([]) array also I know that i need callback or shorter way of it . Do you have any idea for collecting any data from mongodb by node.js? If I call this /Notifies method (http://127.0.0.1:5000/Notifies)
var MongoClient = require('mongodb').MongoClient;
var express = require("express");
var app = express();
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) {
throw err;
} else {
console.log("successfully connected to the database");
}
db.close();
});
app.get('/Notifies', function (req, res) {
// BAD! Creates a new connection pool for every request
console.log('connected');
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
var arr = [];
coll.find({}, function (err, docs) {
docs.each(function (err, doc) {
if (doc) {
console.log(doc);
arr.push(doc);
} else {
res.end();
}
});
});
return res.json(arr);
});
});
var port = Number(process.env.PORT || 5000);
app.listen(port, function () {
console.log("Listening on " + port);
})
Don't use for docs.each instead of this use .toArray so it will return directly a array and then use Json.stringify to convert it into json string array
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
coll.find({}).toArray(function (err, result) {
if (err) {
res.send(err);
} else {
res.send(JSON.stringify(result));
}
})
});
The problem is you are returning the empty array from within the function, before the actual DB operation occurs. You need to move the line return res.json(arr);
into the find function:
app.get('/Notifies', function (req, res) {
// BAD! Creates a new connection pool for every request
console.log('connected');
MongoClient.connect('mongodb://127.0.0.1:27017/Test', function (err, db) {
if (err) throw err;
var coll = db.collection('Notifies');
var arr = [];
coll.find({}, function (err, docs) {
console.log(docs);
docs.each(function (err, doc) {
if (doc) {
console.log(doc);
arr.push(doc);
} else {
res.end();
}
});
return res.json(arr);
});
});
});
Also, for future use, do not reuse variable names in nested functions (you have 3 functions that use the variable err).
Can you please help me with this code. This code is not deleting the value from MongoDB, while I am running this url : http://localhost:3000/delete/57c6713455a6b92e105c5250.
I am getting this response: {"lastErrorObject":{"n":0},"value":null,"ok":1}, but not deleting .
app.get('/delete/:id', (req, res) => {
var uid = req.params.id;
db.collection('quotes').findOneAndDelete({'_id': uid}, (err, result) => {
if (err) return res.send(500, err);
res.send(result);
});
});
In MongoDB you query a document id(_id) by using the ObjectId constructor and not the ObjectId's string. Thus the query needs to be: { '_id': ObjectId(uid) }.
Example
var mongoClient = require('mongodb').MongoClient;
//Include ObjectId
var ObjectId = require('mongodb').ObjectID;
mongoClient.connect("Your connection string", function(err, db) {
var query = {
_id: ObjectId("id_string") // Important to notice
};
var collection = db.collection('your collection');
collection.find(query, function(err, docs) {
console.log(err, docs);
});
});
Suggestion
//Include ObjectId
var ObjectId = require('mongodb').ObjectID;
app.get('/delete/:id', (req, res) => {
var uid = req.params.id;
//Add object id to query object
db.collection('quotes').findOneAndDelete({'_id': ObjectId(uid)}, (err, result) => {
if (err) return res.send(500, err);
res.send(result);
});
});
Yes. thank you i figured where i did wrong. see below correct answer.
var ObjectId = require('mongodb').ObjectID;
app.get('/delete/:id', (req, res) => {
var uid = req.params.id;
db.collection('quotes').findOneAndDelete({'_id': ObjectId(uid) }, (err, result) => {
if (err) return res.send(500, err);
res.send(result);
});
});
This response means, your query is executing properly "OK":1, but the find query is unable to find any doc to delete it.
So before using "findOneAndDelete" use only "findOne" and log the response to check weather you that doc or not.
I'm adding MongoDB to my Express.js Node web app. This is what I got so far:
// in app.js
var mongodb = require('mongodb');
var mongourl = /* … */;
// These are just examples:
app.get('/write', function (req, res) {
mongodb.connect(mongourl, function (err, db) {
db.collection('Users', function (err, coll) {
coll.insert(/* stuff */, function (err) {
res.send(200, 'Done.');
});
});
});
});
app.get('/read', function (req, res) {
mongodb.connect(mongourl, function (err, db) {
db.collection('Users', function (err, coll) {
coll.find({}, function (err, cursor) {
cursor.toArray(function (err, items) {
res.send(200, items);
});
});
});
});
});
Assuming that I want to stick with the default mongodb driver (for now):
Is this pattern right? Do I have to open a new connection to the database in each of my different routes that perform database operations?
If the pattern is right, then how do I deal with the obvious code repetition going on here? Obviously, as it stands now, the code is not acceptable.
Use the new standard, MongoClient. It manages the pool for you, defaults to 5.
//require as a module to be used anywhere.
module.exports = {}
var MongoClient = require('mongodb').MongoClient;
var mongoURI = /* … */;
MongoClient.connect(mongoURI, function(err, db) {
if(err) throw err;
module.exports.users = db.collection('users');
console.log('Connected to Mongo!')
})
then
var db = require('./db.js')
//once connected
//db.users.find()... etc
check out:
http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html
pooling details:
http://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#connection-pool-configuration
Do not close and reopen connection, you're just loosing resources :s