i'm trying create first node js api.
i wroted this code but when i start server.js it's not working.
here code :
var executeQuery = function(res, query){
sql.connect(dbConfig, function (err) {
if (err) {
console.log("Error while connecting database :- " + err);
res.send(err);
}
else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function (err, res) {
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
}
else {
res.send(res);
}
});
}
});
}
when i start it error say :
C:\node\atlasErpApi\server.js:47 res.send(res);
TypeError: res.send is not a function at C:\node\atlasErpApi\server.js:47:43
You are declaring a new variable res as argument to your request.query callback which shadows the res the comes as argument to your executeQuery function.
This should be most obvious at the line res.send(res) which, if you think about it, doesn't make sense at all.
Use different variable names for the two. For example, change the inner one to sqlRes:
var executeQuery = function(res, query) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err);
res.send(err);
} else {
// create Request object
var request = new sql.Request();
// query to the database
request.query(query, function(err, sqlRes) { // <<< CHANGED to sqlRes
if (err) {
console.log("Error while querying database :- " + err);
res.send(err);
} else {
res.send(sqlRes); // This makes more sense now :-)
}
});
}
});
}
Note: Technically this also happens for err - you have an err from request.query's callback shadowing the err from sql.connect's callback. But this usually doesn't matter because you won't need to use the outer err in the inner callback.
Related
I'm new to node,
and not able to understand that how this JS method is returning "list of Tasks" ?
As i don't have any return type and I have passed result as a parameter (form of variable) and in last it is used like a method, return like result(null,err);. So my confusion is that how it is processing ?
From TaskModel
let sql = require('./DbConnection.js');
TaskModel.allTasks = function getAllTasks(result) {
sql.query("select * from task_tbl", function (err, res) {
if (err) {
console.log("Error In Fetching Records..! \n Error : " + JSON.stringify(err, undefined, 2));
result(null,err);
} else {
console.log('All Tasks : ', res);
result(null, res);
}
})
}
I'm calling above method in controller..
From Controller :
let taskModel = require('../model/TaskModel');
module.exports.list_all_tasks = function (req, res) {
taskModel.allTasks(function (err, task) {
console.log("Get All Tasks methods of Controller.");
if (err) {
res.send(err);
}
console.log('Response : ' + task);
res.send(task);
})
}
I am trying to get data from a SQL Server DB using node. I can make a connection and get data by running functions, but I would like to turn the functions into API endpoints.
Based on the error it seems to me that the res variable isn't getting passed down into the last if statement, but I'm not seeing the issue.
I get a res.send is not a function error when using a GET method on this address from Postman.
let mssqlQuery = function(query, res) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err)
res.send(err)
} else {
let request = new sql.Request();
request.query(query, function(err, res) {
if (err) {
console.log("Error while querying database :- " + err)
res.send(err)
} else {
res.send(res) // res.send is not a function
}
})
}
})
}
// GET API
app.get("/api/address", function(req, res) {
var query = "select * from address"
mssqlQuery(query, res)
})
Is the res variable improperly scoped or might I have the wrong approach entirely?
As #Sirko suggested, the res value was shadowed by an other variable. The corrected code:
let mssqlQuery = function(query, res) {
sql.connect(dbConfig, function(err) {
if (err) {
console.log("Error while connecting database :- " + err)
res.send(err)
} else {
let request = new sql.Request();
request.query(query, function(err, resp) { // Changed res to resp
if (err) {
console.log("Error while querying database :- " + err)
res.send(err)
} else {
res.send(resp) // res.send is not a function
}
})
}
})
}
Still new to nodejs not sure what i am doing wrong here, i am trying to return a value from this function. However the variable i am trying to return outhjk is always reset.
function executeQuery( stmt, data ) {
var outhjk = "";
pool.connect(function(err, client, done) {
if(err) {
console.error('error fetching client from pool', err);
}
client.query(stmt, data, function(err, result) {
//call `done()` to release the client back to the pool
done();
if(err) {
return console.error('error running query', err);
}
outhjk = "just work please";
});
});
return outhjk;
}
your query is not operating inside pool.connect its directly returning var = "";
if you are using latest version of node.js you can use new Promise((resolve, reject)=>{});
or if older version use 'async' module or any other module to handle node.js asynchronous functions
client.query is asynchronous. The return statement : return outhjk; will be called before the function executes because return is faster...
The standard way to deal with this is to use a callback function :
function executeQuery( stmt, data, callback ) {
var outhjk = "";
pool.connect(function(err, client, done) {
if(err) {
console.error('error fetching client from pool', err);
}
client.query(stmt, data, function(err, result) {
//call `done()` to release the client back to the pool
done();
if(err) {
return console.error('error running query', err);
}
outhjk = "just work please";
callback(outhjk);
});
});
}
Then to call the function with a callback, you would do something like that :
var stmt = //stmt value here;
var data = //data value here;
executeQuery( stmt, data, function (outhjk) {
//here you can use outhjk
});
Read this to learn the gist off callbacks
With this as a URL:
'api/support-tag/name/myTagName'
This function works properly:
getByName: function (req, res) {
model.Shared_SupportTag.findOne({name: req.params.name}).exec(function (err, results) {
if (err) {
return res.status(400).send({
message: errMsg.Util_ErrorMsg.getErrorMessage(err)
});
}
res.send(results);
})
}
But when I try to call a similar function from within the node server:
supportDoc.category = GetById(item.category);
function GetById(name){
model.Shared_SupportTag.findOne({name: name}).exec(function(err, result){
if(err){
console.log(err)
}else{
console.log(result);
}
})
}
The function does not execute, nor does the error catch, intellisense shows:
err= Reference error; err is not defined
result = Reference error; result is not defined
All I am trying to accomplish is a function call from within the server and not via a URL.
Any solution here? Thanks in advance
In the case of the findOne() method, the positive response (sans error) will either hold a mongoose object or null.
If the same query had been sent using just find(), the result would have been an empty array.
function GetById(name){
model.Shared_SupportTag.findOne({name: name}).exec(function(err, result){
if(err){
console.log(err)
}else{
if (result) console.log(result); //Check whether object exists.
else console.log('Not found!');
}
})
}
Solved:
model.Shared_SupportDoc.find({}).exec(function (err, collection) {
var supportDocs = require('../../data/_seed/support/supportDocs.json');
if (collection.length === 0) {
supportDocs.forEach(function (item) {
var supportDoc = new model.Shared_SupportDoc;
supportDoc.title = item.title;
supportDoc.created = item.date;
supportDoc.icon = item.icon;
supportDoc.likeCount = item.likeCount || 7;
-----> // requires callback - ie asynchronous
GetByName(item.category, function(tagId) {
supportDoc.categoryId = tagId;
-----> // must put save in the callback
supportDoc.save(function (err) {
if (err) {
console.log(supportDoc.categoryId)
console.log('Error: ' + err);
} else {
console.log('Support Doc Seed Complete');
}
});
});
})
}
});}
function GetByName(name, next) {
model.Shared_SupportTag.findOne({name : name}).exec(function (err, result) {
if (!result) {
console.log('Not Found');
next();
} else {
console.log(result._id);
next(result._id);
}
});}
I am trying to accomplish the following (should be quite basic and I must be missing something trivial):
Call a function with string that has a select statement
Wait until the DB call completes and the rows (or json equivalent) is returned
Populate http object to return back
Here is code:
util.js
exports.execute = function( query){
if (connection) {
connection.query(query, function(err, rows, fields) {
if (err) throw err;
console.log("from Util - " + JSON.stringify(rows));
return JSON.stringify(rows);
});
}
};
repo.js
var q = "select * from xxx";
var response;
util.execute(q, function (err, r){
if (err){
throw err;
console.log(err);
}
else {
console.log(r);
res.contentType('application/json');
res.write(r);
res.end();
}
});
My problem is while the code within util.js is called and I can see the json in console, it never comes back to the anonymous call back function in the repo.js.
What am I doing wrong here ?
Update
Thanks Ben
I also found the solution in same line ... here is new code:
repo.js:
var send_data = function (req, res, r){
res.contentType('application/json');
res.write(r);
res.end();
}
exports.all = function(req, res){
var q = "select * from XXX";
var response;
util.execute(req, res,q, send_data);
};
util.js:
exports.execute = function(req, res, query, callback){
if (connection) {
connection.query(query, function(err, rows, fields) {
if (err) throw err;
callback(req, res, JSON.stringify(rows)) ;
});
}
};
util.execute only accepts one parameter in your code. It needs to accept a second callback parameter in order to use it the way you do. (Callbacks aren't magic, they're just function calls)
Something like:
exports.execute = function(query,callback){
if (connection) {
connection.query(query, function(err, rows, fields) {
if (err) throw err;
console.log("from Util - " + JSON.stringify(rows));
callback(null,JSON.stringify(rows));
});
}
};
If you'd like it to behave consistently and accept an error parameter, you might want fill that in:
exports.execute = function(query,callback){
if (connection) {
connection.query(query, function(err, rows, fields) {
callback(err,null);
console.log("from Util - " + JSON.stringify(rows));
callback(null,JSON.stringify(rows));
});
}
};