I am trying to upload two arrays into my sql database.
This is what I have come up with.(this is my server.js using a endpoint from my client side)
My express
app.post("/post-question-answers", async (req, res) => {
console.log("!called");
try {
await sql.connect(config);
// create Request object
var request = new sql.Request();
let results = req.body.results;
let questions = [];
let answers = [];
results.forEach(element => questions.push(element.question));
results.forEach(element => answers.push(element.answer));
for (var i = -1; i < results.length; i++) {
request.input("Question", sql.VarChar, questions[i]);
request.input("Answer", sql.VarChar, answers[i]);
request.execute("dbo.AddQuestionResponses", function(err, recordset) {
if (err) console.log(err);
// send records as a response
res.json(recordset);
});
}
} catch (e) {
console.log(e);
}
});
My sql stored procedrue
alter procedure AddQuestionResponses
#Question nvarchar (50),
#Answer nvarchar (50)
as
insert into QuestionResponses(QuestionWhenAnswered, QuestionResponse)
values (#Question ,#Answer )
However this throws
RequestError: The parameter name Question has already been declared. Parameter names must be unique
I believe this is because
request.input("Question", sql.VarChar, questions[i]);
request.input("Answer", sql.VarChar, answers[i]);
need to be unique and as they are in a for loop they are repeated within the statement. Is there a way in which I can make this a valid transaction with the database and so that these are unique.
Thankyou for your time :)
I solved this issue by putting
var request = new sql.Request();
within the for loop.
Related
I'm trying to assign a MongoDB document object to a Javascript variable running on a Node.js server. I'm having trouble understanding how to do this with the async behavior of the MongoDB driver on Node. In my main app.js file I have the following
// MongoDB
//-------------------------------------------------
var DOC = require('./test_mongodb.js');
console.log(typeof(DOC)); //<---------------- this fails
console.log('Works:', JSON.stringify(DOC)); //<------------this fails
The required file test_mongodb.js is as follows
const config = require('../config/mongodb.config.js'); // <--- This just pulls in the ip:port and database name...nothing special
const mongodb = require('mongodb');
var DOC = {}; // <------------------I want to store a document here
// Client
const mongoClient = mongodb.MongoClient;
// Connection URL
const mongoUrl = 'mongodb://' + config.db.host;
console.log(config.db.host);
// Use connect method to connect to the server
mongoClient.connect(mongoUrl, function(err, client) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
}
else {
console.log("Connected to mongoDB server");
// Select database
const db = client.db('DATA');
// Get the documents collection
var coll = db.collection('TEST');
//We have a cursor now with our find criteria
var cursor = coll.find({"name": "testing"});
//Lets iterate on the result
var count = 0;
cursor.each(function (err, doc) {
if (err) {
console.log(err);
} else {
console.log('Fetched:', doc);
if (count == 3) {
//console.log(typeof(doc));
//DOC = JSON.parse(JSON.stringify(doc)) ;
//console.log(typeof(DOC))
//console.log('Inside:',DOC);
DOC = doc; <----------------------just capture one doc
}
count = count + 1;
}
});
}
// Close connection when done
client.close();
});
console.log(typeof(DOC));
console.log('Inside:',DOC);
module.exports = DOC; // <-------------I want to export the variable here
The output of console.log(typeof(DOC)) in app.js is undefined. Overall, I realize this is a problem with the async behavior, but I don't understand how to correct it. I've read that the solution is to use callback functions, but I don't fully grasp how this is done here with Mongo. In your solution, please give a detailed explanation of how the callbacks are physically working as this is my main confusion.
One other side question...is there a difference between cursor.each and cursor.forEach?
The problem here is that the module.exports assignment is happening before the query is complete.
Your environment probably supports Promises, so you can return one here. Here's how your code should like:
test_mongodb.js
const config = require('../config/mongodb.config.js'); // <--- This just pulls in the ip:port and database name...nothing special
const mongodb = require('mongodb');
var DOC = new Promise(function(resolve, reject) {
// Client
const mongoClient = mongodb.MongoClient;
// Connection URL
const mongoUrl = 'mongodb://' + config.db.host;
console.log(config.db.host);
// Use connect method to connect to the server
mongoClient.connect(mongoUrl, function(err, client) {
if (err) {
console.log('Unable to connect to the mongoDB server. Error:', err);
} else {
console.log("Connected to mongoDB server");
// Select database
const db = client.db('DATA');
// Get the documents collection
var coll = db.collection('TEST');
//We have a cursor now with our find criteria
var cursor = coll.find({
"name": "testing"
});
//Lets iterate on the result
var count = 0;
cursor.each(function(err, doc) {
if (err) {
console.log(err);
} else {
console.log('Fetched:', doc);
if (count == 3) {
resolve(doc);
}
count = count + 1;
}
});
}
// Close connection when done
client.close();
});
})
module.exports = DOC;
Then wait for the promise to resolve in the parent.
app.js
require('./test_mongodb.js').then(function(DOC) {
console.log(DOC);
}, function(err) {
console.log(err);
});
I'm running a query to fetch the list of new users. Query is correct. It returns 15 users. I push the resultset into a javascript array but only the last record from the resultset is getting saved.
Here's my code:
var query = `SELECT *
FROM users
WHERE (status ='New')`;
var query = connection.query(query),
response = []; // this array will contain the result of our db query
query
.on('error', function (err) {
console.log(err);
})
.on('result', function (res) {
// it fills our array looping on each user row inside the db
response.push(res);
/*
for (var key in res) {
if (res.hasOwnProperty(key)) response.push(res[key]);
}
*/
})
.on('end', function () {
console.log('console')
});
As you can see response.push(res); is the line of code where I do this. Below that I have comment a few lines. I tried that option to push each row from the resultset but it ain't giving any results.
try a for loop
for(var i in res){
response.push(res[i]);
}
I maybe underestimate your test but you maybe check result at the wrong place.
You should do it on the 'end' callback.
.on('end', function () {
console.dir(res)
});
I'm trying to reach different select's from another select with MongoDB database with mongoose to redirect to Emberjs front-end.
If the text above it's not clear, look at the schema of the database:
// I already get the exam content given an id
Exam:{
...
collections:[{
question: Object(Id)
}]
...
}
and in the question schema it's:
// I want to get content of this giving an id
question:{
...
questions: String, // I want to get this given an Id exam
value: Number // and this
...
}
I tried to get it getting the objects id of the collections and then make a for to extract each question, and save the returned values into a json variable like this:
Test.findById(id, 'collections', function(err, collections){
if(err)
{
res.send(err);
}
var result ={}; //json variable for the response
// the for it's with the number of objectId's that had been found
for(var i = 0; i < collections.collections.length; i++)
{
// Send the request's to the database
QuestionGroup.findById(collections.collections[i].id, 'questions').exec(function(err, questiongroup)
{
if(err)
{
res.send(err);
}
// save the results in the json
result.questiongroup = questiongroup;
// prints questions
console.log(result);
});
// it return's {}
console.log(result);
}
// also return {}
console.log(result);
res.json({result: result});
});
It's there a way to save the requests into a variable and return it like a json to the front end?
since the query within the loop executes in async manner you'll have send response once everything finished execution.
For eg.
Test.findById(id, 'collections', function(err, collections) {
if (err) {
res.send(err);
}
var result = []; //json variable for the response
function done(result) {
res.json({
result
});
}
for (var i = 0, l = collections.collections.length; i < l; i++) {
// i need needs to be in private scope
(function(i) {
QuestionGroup.findById(collections.collections[i].id, 'questions').exec(function(err, questiongroup) {
if (err) {
res.send(err);
}
// save the results in the json
result.push(questiongroup);
if (l === i + 1) {
done(result);
}
});
})(i);
}
});
NOTE: untested, and you might have to handle errors appropriately
What's the correct way to process information from a database query after it has been retrieved.
Assuming the the below example that dataObj is just a js object that contains a field, name, which is defined, is this how I should be processing data in node.js?
EDIT:
forgot to mention that of course I can't return the data object because this is an async call.
function processData(dataObj){
if(dataObj.name == "CS"){
console.log("true");
}
}
function getData(anon)
var dat = .... sql query that works and its an object now that works correctly...
anon(dat);
}
getData(processData);
Here's a snippet of some code i'm working on using mongoose:
var db = mongoose.createConnection(uristring)
, mongoose = require('mongoose');
db.once('open', function(){
var recipientSchema = mongoose.Schema({
username: String,
recipientEmail: String
});
var Recipient = db.model('Recipient', recipientSchema);
Recipient.find( {username: user }, function(err, recipients){
res.json(recipients);
})
})
Hope that helps!
One of NodeJS' strengths is streaming support. I would expect from a proper SQL driver to give me one row at the time. If I want I can collect all of them, but most of the time I don't want all the rows in memory. Instead I would stream them one by one to a consumer.
My preferred DB code would look like...
var db = require('<somedriver>');
var sqlStatement = ".... sql query that works and its an object now that works correctly...";
var query = db.execute(sqlStatement);
query.on('row', function (row) {
// Do something with a row object...
console.log("This is a row", row);
});
query.on('done', function (err, rowcount) {
if (err) { throw err; } // or do something else...
console.log("Number of rows received", rowcount)
});
Hope this helps
How do you access mongodb count results in nodejs so the result can be accessible to the asynchronous request? I can get the result and update the database but the asynchronous request fails to access the vars or the vars are empty and the vars appear to be updated when the next asynchronous request is made. The request must not be waiting for the query to finish and the next request is filled with the previous request's variables.
testOne.increment = function(request) {
var MongoClient = require('mongodb').MongoClient,
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/bbb_tracking', function(err, db) {
if (err) throw err;
collection = db.collection('bbb_tio');
collection.count({vio_domain:dom}, function(err, docs) {
if (err) throw err;
if (docs > 0) {
var vio_val = 3;
} else {
var vio_val = 0;
}
if (vio_val === 3) {
event = "New_Event";
var inf = 3;
}
db.close();
console.log("docs " + docs);
});
});
};
In the above, even when the vars are set in scope they are not defined asynchronously. Can I get some guidance on structuring this properly so the vars are populated in the callback. Thank you!
Since the count function is asynchronous, you'll need to pass a callback to the increment function so that when the count is returned from the database, the code can call the callback.
testOne.increment = function(request, callback) {
var MongoClient = require('mongodb').MongoClient,
format = require('util').format;
MongoClient.connect('mongodb://127.0.0.1:27017/bbb_tracking', function(err, db) {
if (err) throw err;
var collection = db.collection('bbb_tio');
// not sure where the dom value comes from ?
collection.count({vio_domain:dom}, function(err, count) {
var vio_val = 0;
if (err) throw err;
if (count > 0) {
vio_val = 3;
event = "New_Event";
var inf = 3;
}
db.close();
console.log("docs count: " + count);
// call the callback here (err as the first parameter, and the value as the second)
callback(null, count);
});
});
};
testOne.increment({}, function(err, count) {
// the count would be here...
});
(I don't understand what the variables you've used mean or why they're not used later, so I just did a bit of a clean-up. Variables are scoped to function blocks and hoisted to the function, so you don't need to redeclare them in each if block like you had done with vio_val).
You could use the 'async' module. It makes the code a lot cleaner and easier to debug. Take a look at the code in GitHub for adduser.js & deleteuser.js in the following post
http://gigadom.wordpress.com/2014/11/05/bend-it-like-bluemix-mongodb-using-auto-scaling-part-2/
Regards
Ganesh
length give you count of result array
const userdata = await User.find({ role: role, 'name': new RegExp(searchkey, 'i') },{date: 0,__v:0,password:0}).
sort(orderObj)
.limit(limit)
.skip(skip);
console.log(userdata.length);