I'm trying to use the spread method to accumulate promised results that I've read in this thread with Q.js. It works in another block of code but not in the following app.get example. I want to chain queries using Sequelize and mongoose and pass all the returned data to the spread method. Here's my attempt:
var db = require('./db/managedb'); // Sequelize
var mongo_models = require('./db/mongo_model')(mongoose);
var WB = mongo_models.Webdata,
Est = mongo_models.Estimate;
app.get('/p/:tagId', function(req, res){
var filename = req.param("tagId");
var mysql = db.db.query('CALL procedure()').then(function(rows) {
console.log(rows);
}); // Sequelize
var nosql = WB.find().exec(function(err,k){
console.log(k);
}) // Mongoose
var nosql2 = Est.find().exec(function(err,la){
console.log(la);
}) // Mongoose
Q.try(function(){
return mysql
}).then(function(mysqls){
return [ mysqls,nosql]
}).then(function(mysqls,nosqls){
return [mysqls,nosqls,nosql2]
}).spread(function(mysqls,nosqls,nosql2s){
res.render(filename+'.html', {my:mysqls,wb:nosqls,est:nosql2s})
}).catch(function(error){
console.log('fail')
})
})
I'm just getting a blank page with Cannot GET /p/5 and there's no "fail" shown in the console.log. Here's my original code that works, but it's suffering from callback hell.
app.get('/p/:tagId', function(req, res){
var filename = req.param("tagId");
db.db.query('CALL procedure()').then(function(rows) {
WB.find().exec(function(err,wb){
Est.find().exec(function(err,est){
res.render(filename+'.html', {my:rows,wb:wb,est:est})
})
})
}).catch(function (error) {
console.log('own: database error');
})
})
You can try using them as proxies:
app.get('/p/:tagId', function(req, res){
var filename = req.param("tagId");
var rows = db.db.query('CALL procedure()');
var wb = WB.find().exec();
var est = Est.find().exec();
Promise.props({my: rows, wb: wb, est: est}).then(function(obj){
res.render(filename+'.html', obj)
}).catch(function (error) {
console.log('own: database error'); // not sure I'd just supress it
});
});
Bluebird is already available through sequelize if you don't have it in your project.
Alternatively, you don't have to put them in specific variables:
app.get('/p/:tagId', function(req, res){
var filename = req.param("tagId");
Promise.props({
my: db.db.query('CALL procedure()'),
wb: WB.find().exec(),
est: Est.find().exec()
}).then(function(obj){
res.render(filename+'.html', obj);
}).catch(function (error) {
console.log('own: database error'); // not sure I'd just supress it
});
});
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('/');
});
})
I'm just getting started with Nodejs, so please bear with me
I store my DB setting on the first JS, connect.js :
var mysql = require('mysql');
module.exports = function(connectDB) {
var connectDB = {};
connectDB.connection = mysql.createConnection({
//db params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
return connectDB;
};
Then I stored my query in another JS file, lets call it dbManager.js :
var db = require('./connect')(connectDB);
var test_connection = connectDB.connection.query('SELECT * FROM `test`', function (error, results, fields) {
console.log(results);
});
exports.test = test_connection;
My goal is to pass the connection variable from connect.js to dbManager.js, so I could use it for running some queries.
The above code return an error, which said the variable is not passed successfully to dbManager.js :
ReferenceError: connectDB is not defined
Thanks in advance
The syntax error is because you cant define variables within an object literal using var.
e.g., you can't do the following,
var t = {
"r": 4,
var g = 5;
};
You can do this,
var t = {
"r": 4,
"g" : 5
};
And to access the properties of the object you can do,
console.log(t["r"]);
console.log(t.g);
In your code the problem is declaring a variable inside an object literal. Yo could do,
var connectDB = {};
connectDB.connection = mysql.createConnection({
//DB params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connectDB.connection.threadId);
});
return connectDB;
Edit1 As per OP's comments,
connect.js:-
Changes- No need of the connectDB param, using module.exports functionality.
var mysql = require('mysql');
var connectDB = {};
connectDB.connection = mysql.createConnection({
//db params
});
connectDB.connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connectDB.connection.threadId);
});
module.exports = connectDB;
dbManager.js:-
var db = require('./connect');//removed the parameter
//use db variable to process queries as returned from the above require statement.
var test_connection = db.connection.query('SELECT * FROM `test`', function (error, results, fields) {
console.log(results);
});
exports.test = test_connection;
**you can do it like this
connection.js**
var mysql=require('mysql');
// Database Connection
var connection = mysql.createConnection({
host : hostname,
user :username,
password : password,
database : databasename,
multipleStatements:true
});
try {
connection.connect();
} catch(e) {
console.log('Database Connetion failed:' + e);
}
module.exports=connection;
**you can use this connection file in your dbmanager file like
this..**
var db = require('./connection.js');var test_connection =
connection.query('SELECT * FROM test', function(err,result) {
console.log(result);
});
Will something like this work for you? You can have a file that returns a connection object from the pool:
var mysql = require('mysql');
module.exports = function() {
var dbConfig = {...};
var database = mysql.createPool(dbConfig);
return {
getConnection: function(callback) {
// callback(error, connection)
database.getConnection(callback);
}
};
};
Wherever you need to use it, you can require it as follows:
var connector = require('./db-connector')();
Then use it like this:
connector.getConnection(function(error, connection) {
// Some code...
// Be sure to release the connection once you're done
connection.release();
});
This is how I store config data to pass around on my node server. I call it config.js and .gitignore it. I keep a sample copy called config.sample.js
let config = {};
config.mysql-host='localhost' || process.env.MYSQL_HOST;
config.mysql-user='me' || process.env.MYSQL_USER;
config.mysql-secret='secret' || process.env.MYSQL_SECRET;
config.mysql-database='my_db' || process.env.MYSQL_DB;
module.exports = config; //important you don't have access to config without this line.
To use it I would do the following.
const config = require('./config');
const mysql = require('mysql');
const connection = mysql.createConnection({
host: config.host,
user: config.user,
password: config.password,
});
connection.connect((err) => {
if(err) {
console.error(`error connecting: ${err.stack});
return;
}
console.log(`connected`);
});
const test_connection = connectDB.connection.query('SELECT * FROM `test`'(error, results, fields) => {
console.log(results);
});
I am trying to load my data in the web api by using postman to test it out. So I am able to get my query right on console.log(doc) on node.js but when i tried to return callback and post on postman, it gives me [object Object]and does not give back the data itself just object. This is my code.
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var url = 'mongodb://localhost:27017/myproject';
module.exports = {
postCollection : function(req, res){
var issueQty = req.body.issueQty;
var itemDescrip = req.body.itemDescrip;
MongoClient.connect(url, function(err, db) {
assert.equal(null, err);
updateRecord(db, req, function(doc) {
res.send('Record Found. Now updating this document...' + itemDescrip + '
Record Updated. This is the new record '
+ doc )
db.close();
});
});
}
}
var updateRecord = function(db, req, callback) {
var cursor = db.collection('documents').find({'Item Description':
req.body.itemDescrip, 'Issued QTY': req.body.issueQty})
cursor.each(function(err,doc){
assert.equal(err,null);
if(doc != err){
console.log('Successfully queried');
console.log(doc);
return callback(doc);
} else{
callback(doc);
}
});
db.collection('documents').updateMany(
{ 'Item Description': req.body.itemDescrip},
{
$set: { 'Issued QTY': req.body.issueQty }
}
/*function(err, results) {
console.log(results);
console.log('Done');
});*/
)};
So right now I am lost as to where I have done wrong to output [object Object] instead of the queried data. Any help is appreciated, thanks!
So I managed to find the answer looks like I had to use callback(JSON.stringify(doc));
for postman to be able to read it and output the query.
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 kinda new to node.js and mongo and i'm having a little problem. I can't bulk insert documents into mongodb using ajax on client and nodejs/express on server. Here is my client code:
<button class="btn>Send</button>
data = {'test':'test1','test':'2','test':'test1','test':'test2','test':'test1','test':'test2'}
$(".btn").click(function(){
$.ajax({
url: 'http://localhost:8000/2',
type: 'post',
dataType: 'json',
data: data
});
});
And here is my route handler in node:
app.post('/2', function(req, res){
var docs = [];
for(var i = 0; i < 10000; i++) {
docs[i] = req.body;
}
db.collection('test', function(err, collection){
collection.insert(docs, function(err, result) {
if (!err) {
console.log(result);
res.end();
} else {
throw err
}
})
});
})
I'm getting data nicely with console.log(docs), but my test collection is empty. What am i missing? Thanks
app.post('/2', function(req, res){
var docs = req.body.data; // ur json data is now in node end
var i=0;
var bulk = test.collection.initializeUnorderedBulkOp(); // test is the model name. I used mongoose
// now using loop insert all json data inside bulk variable
for (i = 0; i < docs.length; i += 1) {
bulk.insert(docs[i]);
}
//after insertion finished u might need node-async module, to insert first
//then asynchronously execute bulk
bulk.execute(function (errx) {
if (errx) { return next(errx); }
console.log('Success');
});
})
you need to define test schema and test model correctly.
For further details you can read following links
https://docs.mongodb.com/manual/reference/method/Bulk.insert/
You can try mongoose variant. It is a bit more comfy and have some benefits.
const mongoose = require('mongoose');
app.post('/2', function(req, res){
var docs = req.body.data;
const Entity = mongoose.model('test', new Schema({}, {strict: false}));
Entity.insertMany(docs).then(x => res.send(x)).catch(e => res.send(e));
}
You can also define mongoose schema and change strict to true to have db validation.
new Schema({
foo: String,
bar: Number
}, {strict: true})