I am trying to write an api that queries a mssql database. however my response from the api is always Promise { undefined }
app.get('/api/:year/:month', (req, res) => {
var data = getData(req.params.month, req.params.year);
console.log(data);
res.send(data);
});
async function getData(m, y) {
var query = "SELECT ...";
sql.connect(Config, (err) => {
if (err) {
console.log("Error while connecting to database :- " + err);
} else {
var request = new sql.Request();
request.query(query, function (err, rs) {
if (err) {
console.log("Error while querying database :- " + err);
} else {
return rs.recordset;
}
sql.close();
})
}
})
I'm assuming I need to await the result somehow as if I log the response inside the data function it is populated, however I can't seem to get anything to work.
You are creating it a callback style function but not really taking the value. You need to convert it to promise based like this and use async/await
app.get("/api/:year/:month", async (req, res) => {
const data = await getData(req.params.month, req.params.year);
console.log(data);
res.send(data);
});
async function getData(m, y) {
const query = "SELECT ...";
await sql.connect(Config);
const request = new sql.Request();
const rs = await request.query(query);
return rs.recordset;
}
Related
I have written the following code in Nodejs which is saving data in MongoDB:
function insertDoc(db,data){
return new Promise(resolve => {
callback=db.collection('AnalysisCollection').insertOne(data).then(function(response,obj){
console.log("Inserted record");
resolve(obj);
//console.log(obj);
// response.on('end',function(){
// resolve(obj);
// });
//return resolve(obj);
}).then(() => { return obj }
).catch(function(error){
throw new Error(error);
});
})
}
I am calling the above function from the main function like this:
async function cosmosDBConnect(nluResultJSON){
try{
//console.log("Inserting to cosmos DB");
console.log(nluResultJSON);
var url = config.cosmos_endpoint;
var result="";
var data = JSON.parse(JSON.stringify(nluResultJSON));
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
var db = client.db('NLUAnalysisDB');
// insertDoc(db, data, function() {
result=insertDoc(db, data, function() {
console.log(result);
client.close();
//return data._id;
});
});
}
catch (e) {
console.log(e);
}
}
module.exports = { cosmosDBConnect };
But in cosmosDBConnect, I am getting 'undefined' for the result, though in insertDoc I am getting the output for'obj' with _id for the inserted record.
Please help me to return this _id to cosmosDBConnect.
You are use callbacks inside of async function, which creates internal scopes. So your return aplies to them instead of whole function. You should use Promise-based methods inside of async function using await (without callbacks) or wrap whole function into own Promise otherwise.
Example:
function cosmosDBConnect(nluResultJSON) {
return new Promise((resolve, reject) => {
var url = config.cosmos_endpoint;
var result = '';
var data = JSON.parse(JSON.stringify(nluResultJSON));
MongoClient.connect(url, function(err, client) {
if (err) return reject(err);
assert.equal(null, err);
var db = client.db('NLUAnalysisDB');
insertDoc(db, data).then(obj => {
console.log(obj);
client.close();
return resolve(data._id);
});
});
});
}
Also you need to understand that your insertDoc return Promise and do not accept callback you tried to pass.
Ref: async function
result = insertDoc(db, data).then((data) => {
console.log(data);
}).catch(err => console.error(err));
I am rewriting an ASPX application using Node. Part of this application is pulling data from a table in SQL Server. I am doing this using async functions to try and force the data to be pulled prior to continuing on. It is essential that I have the data before the next step. However, when it returns from the await the response is null.
const getUserGroups = async (user) => {
let qry = `Select role from [xxxxx] where LOWER(yyyyy)='${user.toLowerCase()}'`;
let groups = await dataQuery.Select(qry, dbList.MCAIntranet)
console.log("Groups: ", groups); //This is undefined
return groups;
// })
}
Here is the Select function:
const Select = async (query, database) => {
// console.log(config[database]
sql.connect(config[database], (err) => {
if (err) console.log(err);
let request = new sql.Request();
request.query(query, (err, recordset) => {
console.log(recordset)//displays correct data
if (err) {
console.log(err);
return null
}
return recordset;
})
});
}
I am using the mssql module, but since I am fairly new to Node I am uncertain where my mistake lies.
Thanks in advance for looking at this.
In you current code, you don't return anything from your Select function. Espectially you are not wrapping your sql code in promise.
You say, you are using the mssql package. This already supports async/await, so you should use the apropriate async calls instead of callbacks.
const Select = async (query, database) => {
try {
await sql.connect(config[database]);
let request = new sql.Request();
let recordset = await request.query(query);
return recordset;
} catch (e) {
console.log(e);
return null;
}
}
Furthermore you should read about parameterized queries, because currently your code is quite unsafe, ie it is vulnerable to SQL injections and invalid syntax errors.
You can either wrap your implementation with a Promise object, or return Promise.resolve(data);, and return Promise.reject(err):
const Select = async (query, database) => {
return new Promise((resolve, reject) => {
// console.log(config[database]
sql.connect(config[database], (err) => {
if (err) reject(err);
let request = new sql.Request();
request.query(query, (err, recordset) => {
console.log(recordset)//displays correct data
if (err) {
console.log(err);
reject(err);
}
resolve(recordset);
})
});
});
}
I start to develop a simple web application with NodeJS. and when I try to get a list record from SQL Server to show on the list page but somehow it's not working.
Here is the code :
const express = require("express");
const bodyParser = require("body-parser");
const sql = require("mssql");
const DBUtils = require("./DBUtils");
const app = express();
app.get("/all", (req, res, next) => {
let mypromise = new Promise((reso, rej) => {
let nameList = DBUtils.getNameList(sql);
if (nameList !== null || typeof nameList !== "undefined") {
reso(nameList);
} else {
rej("Error");
}
})
.then((result) => {
res.send(result);
})
.catch((err) => {
console.log(err);
});
});
app.get("/", (req, res, next) => {
console.log("the / route");
res.send("<h1>Hello to NodeJS</h1>");
});
app.listen(5003);
My DBUtils
const config = {
user: "sa",
password: "123",
server: "DESKTOP-7KGJI7L", // You can use 'localhost\\instance' to connect to named instance
database: "java",
options: {
encrypt: false,
},
};
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) console.log(err);
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
return nameList;
});
});
};
exports.getNameList = getNameList;
I pretty sure something wrong in Promise line but don't know how to fix it. Any suggest?
I think you are a newbie in Nodejs You made a common mistake. You did not use promise pattern correctly. Also, no need to pass next callback unless required.
Change getNameList as below :
const getNameList = (sql) => {
let nameList = "";
let errorString = "";
// Create connection
return new Promise (function(resolve,reject) {
sql.connect(config, function (err) {
// Err
if (err) {
console.log(err);
reject(err)
}
// Create Request object
let sqlRequest = new sql.Request();
// QueryString
let queryString = `select * from NAME`;
// Run the query
sqlRequest.query(queryString, (err, data) => {
if (err) {console.log(err)
reject(err)
}
//console.log(data); //data.recordset(array)[index].name
data.recordset.forEach((el) => {
nameList += `<li>${el.name}</li>`;
});
resolve(nameList);
});
});
})
};
Change app.get("/all") as below:
app.get("/all", (req, res) => {
DBUtils.getNameList(sql).then(function(list) {
res.status(200).send(list)
}).catch(function(err) { //handle error here
res.status(500)
})
})
Moreover, learn how to use promises and async-await.
Use appropriate body-parser as per requirement ie json, text etc.
Learn how and when to use next
Im trying to build a rest api, fetching a nested mysql queries.
When i fetch the first query, this return a array, then with this array i need to fetch data with another query for each value through a array.map
when the script running, always log a empty array, i think must be cause of promises. any help please?
//this the mysql queries
const getTournaments = 'SELECT ID FROM wp_posts WHERE post_type = "tournament"'
const getTournamentGame = 'SELECT meta_value FROM wp_postmeta WHERE meta_key = "tournament_game" AND post_id = ?'
async function fetchType(id){
return new Promise ((res, rej) => {
try{
pool.query(getTournamentGame, [id], (err, rows) => {
if (err) {
return rej(err)
}else {
return res(rows[0].meta_value)
}
})
} catch(err){
console.log(err)
}
})
}
async function mapeado(array) {
return new Promise (async (resolve,rej) => {
try{
var arr = []
array.map((item) => {
fetchType(item.ID).then((res) => {
var tourData = {
id: item.ID,
type: res
}
return tourData
}).then((data) => {
arr.push(data)
})
})
return resolve(arr)
} catch(err) {
console.log(err)
}
})
}
//making rest api
app.get('/tournaments', async (req, res) => {
pool.query(getTournaments, (err, rows) => {
mapeado(rows).then(console.log)
})
})
I am using node js express and calling model from the controller.When I call model form controller and getting a result in result variable and print it in console.log(result) it's undefined.
Controller
var user_model=require('../models/user');
exports.get_user = function(req, res) {
var result = user_model.get_users();
console.log(result);
}
Model
var connection=require('../config/connection');
exports.get_users = function() {
connection.query('SELECT * FROM users', function(err, rows) {
if(err) {
retrun err;
}
return rows;
});
}
This is happening because you are consoling the result before the query has finished. Node is asynchronous. Unlike php node doesn't wait for the query to finish before going to the next line.
Use promise to handle async calls
// **Controller**
var user_model = require('../models/user');
exports.get_user = function (req, res) {
user_model.get_users().then((result) => {
console.log(result);
}).catch(err => console.log(err));
}
// **Model**
var connection = require('../config/connection');
exports.get_users = function () {
return new Promise((resolve, reject) => {
connection.query('SELECT * FROM users', function (err, rows) {
if (err) {
reject(err);
}
resolve(rows);
});
}
})
}