I am facing problem when I try to invoke SQL resultSet for second time, and I get error Cannot read property "resultSet" from undefined. so I just wondering how to reuse resultSetor call multiple resultSet.
Main.js
function getAuthen(){
var username = $("#AuthUsername").val();
var password = $("#AuthPassword").val();
var invocationData = {
adapter: "ConnectDB",
procedure : 'getauthentication',
parameters : [username, password]
};
WL.Client.invokeProcedure(invocationData, {
onSuccess : getAuthenSuccess,
onFailure : getAuthenFailure
});
}
function getAuthenSuccess(result){
if(result.invocationResult.resultSet.length > 0)
{
$("#AuthDiv").hide();
$("#header_main").show();
$("#Menu").show()
$('#DisplayName').html(result.invocationResult.resultSet[0].NME);
$('#DisplaySurname').html(result.invocationResult.resultSet[0].SURNME);
} else {
getAuthenFailure();
}
}
function getAuthenFailure(result){
var alertTitle = "Fail to Login";
var alertText = "Please Enter Username and Password Correctly";
WL.SimpleDialog.show(alertTitle, alertText,[
{
text : 'OK',
handler : getLogout
}
]);
}
//***************************** END ************************\\
//*********** Get Problem On Going ************************//
function queryProblemOnGoing(){
var invocationDataP = {
adapter: "ConnectDB",
procedure : 'getproblemOngoing',
parameters : []
};
WL.Client.invokeProcedure(invocationDataP, {
onSuccess : getProblemOnGoingSuccess,
onFailure : getProblemOnGoingFailure
});
}
function getProblemOnGoingSuccess(result){
if(result.invocationResult.resultSet.length > 0)
{
window.alert("Success");
$("#Menu").show()
// displayQueryOnGoing(result.invocationResult.resultSet);
} else {
window.alert("Fail");
//getProblemOnGoingFailure();
}
}
function getProblemOnGoingFailure(result){
var alertTitle = "Fail to Retrive Data";
var alertText = "Please Contact Administrator";
WL.SimpleDialog.show(alertTitle, alertText,[
{
text : 'OK'
}
]);
}
function displayQueryOnGoing(result) {
for (var i =0; i < result.length; i++)
{
$('#problemOnGoingTable').append("<tr><td>" + result[i].CALLNO + "</td></tr>");
$('#problemOnGoingTable').append("<tr><td>" + result[i].CALLNOREF + "</td></tr>");
}
}
ConnectDB Adapter
var AuthenStatement = WL.Server.createSQLStatement("select NME, SURNME, CUS_ID from USERS where USERID = ? AND PASSWD = ?");
var problemOngoingStatement = WL.Server.createSQLStatement("select * from CALL”);
function getauthentication(userid, password) {
return WL.Server.invokeSQLStatement({
preparedStatement : AuthenStatement,
parameters : [userid, password]
});
}
function getproblemOngoing() {
return WL.Server.invokeSQLStatement({
preparedStatement : problemOngoingStatement,
parameters : []
});
}
I am not really sure how it is working the first time, or which part is working on the first time.
Anyway, I suspect that the problem is here:
for (var i =0; i < result.length; i++)
Perhaps you should change result.length to result.invocationResult.resultSet.length.
Related
I am trying to link two tables in DynamoDB for an Amazon Alexa skill. I am using two tables one is named 'yesno' and the other 'fixtures'. The fixtures table has a list of 22 names in each record and these names are in the 'yesno' table along with the column 'goals'. Here you can see the tables in more detail. Name Table:
Fixtures Table:
As you can see there are names that link the two databases together. I use the team1 column to search the fixtures table and use the name column to search the name table. Here is my code for searching:
function readDynamoItem(params2, callback) {
var AWS = require('aws-sdk');
AWS.config.update({region: AWSregion});
var dynamodb = new AWS.DynamoDB();
const names = new Array();
console.log('reading item from DynamoDB table');
dynamodb.scan(params2, function (err, data){
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data); // successful response
//tried to put a automatic loop for the long bit of code after this but didnt work so anyone with insight on this too would be helpful
/*for(var i = 1; i <= 11; i++){
var str = "T1S";
var pos = i.toString();
pos = str.concat(pos);
names[i] = jsonToString(data.Items[0].pos);
}
for(var j = 1; j <= 11; j++){
str = "T2S";
pos = j.toString();
pos = str.concat(pos);
names[(j+11)] = jsonToString(data.Items[0].pos);
}
*/
names[1] = jsonToString(data.Items[0].T1S1);
names[2] = jsonToString(data.Items[0].T1S2);
names[3] = jsonToString(data.Items[0].T1S3);
names[4] = jsonToString(data.Items[0].T1S4);
names[5] = jsonToString(data.Items[0].T1S5);
names[6] = jsonToString(data.Items[0].T1S6);
names[7] = jsonToString(data.Items[0].T1S7);
names[8] = jsonToString(data.Items[0].T1S8);
names[9] = jsonToString(data.Items[0].T1S9);
names[10] = jsonToString(data.Items[0].T1S10);
names[11] = jsonToString(data.Items[0].T1S11);
names[12] = jsonToString(data.Items[0].T2S1);
names[13] = jsonToString(data.Items[0].T2S2);
names[14] = jsonToString(data.Items[0].T2S3);
names[15] = jsonToString(data.Items[0].T2S4);
names[16] = jsonToString(data.Items[0].T2S5);
names[17] = jsonToString(data.Items[0].T2S6);
names[18] = jsonToString(data.Items[0].T2S7);
names[19] = jsonToString(data.Items[0].T2S8);
names[20] = jsonToString(data.Items[0].T2S9);
names[21] = jsonToString(data.Items[0].T2S10);
names[22] = jsonToString(data.Items[0].T2S11);
}
});
var goals = new Array();
//for loop to be used later when expanding
//for(var i = 1; i <= 22; i++){
var params = {
TableName: 'yesno',
FilterExpression: 'name = :value',
ExpressionAttributeValues: {':value': {"S": names[2]}}
};
dynamodb.scan(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data); // successful response
var temp = jsonToString(data.Items[0].goals);
goals[1] = temp;
}
callback(goals[1]);
});
//}
}
function jsonToString(str){
str = JSON.stringify(str);
str = str.replace('{\"S\":\"', '');
str = str.replace('\"}', '');
return str;
}
I am trying to use the goals array to print each persons goals off but right now it won't even print one persons and instead will print an undefined object of some sort. I'm guessing it just can't search the names table using the names array. The main bit of code I am having a problem with is when searching the yesno table as you can see in this code:
var goals = new Array();
//for loop to be used later when expanding
//for(var i = 1; i <= 22; i++){
var params = {
TableName: 'yesno',
FilterExpression: 'name = :value',
ExpressionAttributeValues: {':value': {"S": names[2]}}
};
dynamodb.scan(params, function (err, data) {
if (err) console.log(err, err.stack); // an error occurred
else{
console.log(data); // successful response
var temp = jsonToString(data.Items[0].goals);
goals[1] = temp;
}
callback(goals[1]);
});
//}
I know for sure there is nothing wrong with the implementation but here it is just in case it is helpful:
const handlers = {
'LaunchRequest': function () {
this.response.speak('welcome to magic answers. ask me a yes or no question.').listen('try again');
this.emit(':responseReady');
},
'MyIntent': function () {
var MyQuestion = this.event.request.intent.slots.MyQuestion.value;
console.log('MyQuestion : ' + MyQuestion);
const params2 = {
TableName: 'Fixtures',
FilterExpression: 'team1 = :value',
ExpressionAttributeValues: {':value': {"S": MyQuestion.toLowerCase()}}
};
//const params3 = {
// TableName: 'Fixtures',
// FilterExpression: 'team2 = :value',
// ExpressionAttributeValues: {':value': {"S": MyQuestion.toLowerCase()}}
//};
readDynamoItem(params2, myResult=>{
var say = MyQuestion;
say = myResult;
say = 'The top scorer for ' + MyQuestion + ' is ' + myResult;
this.response.speak(say).listen('try again');
this.emit(':responseReady');
});
},
'AMAZON.HelpIntent': function () {
this.response.speak('ask me a yes or no question.').listen('try again');
this.emit(':responseReady');
},
'AMAZON.CancelIntent': function () {
this.response.speak('Goodbye!');
this.emit(':responseReady');
},
'AMAZON.StopIntent': function () {
this.response.speak('Goodbye!');
this.emit(':responseReady');
}
}
;
I'm trying to insert data in my local database. When I get to opening the db it give me that error. I searched and found that it must be in a try catch block. I did it but still the same problem.
var APP_ID = "C44F83E2-6CCA-9BAD-FF5A-CE8C869F7300";
var SECRET_KEY = "39C7F777-F0A0-4DEB-FF35-D147FB5BEB00";
var VERSION = "v1";
var categories = [] ;
var createStatement = "CREATE TABLE IF NOT EXISTS categories(id INT NOT NULL PRIMARY KEY"
+",name VARCHAR(36) NOT NULL "
+",iconName VARCHAR(20) NOT NULL"
+",category VARCHAR(19) NOT NULL"
+",score INT NOT NULL)";
var selectAllStatement = "SELECT * FROM categories";
var insertStatement = "INSERT INTO categories(name,category,iconName,score) VALUES (?,?,?,?)";
var dropStatement = "DROP TABLE categories";
var current_item=0;
var total_item=2;
var db;
//database varsion setting
var version = 1.0;
//database name setting
var dbName = "GuessWhat";
//database display name setting
var dbDisplayName = "Guess_What_db";
//database size setting
var dbSize = 2 * 1024 * 1024;
function selectDB() {
if (window.openDatabase) {
//openDatabase(name, version, displayname, estimatedsize, callback);
try {
db = openDatabase(dbName, version, dbDisplayName, dbSize);
} catch (e) {
// TODO: handle exception
console.log(e);
}
dropTable(db);
createTable(db);
console.log("test base");
for(var c in categories)
{console.log(categories[c].getName());
insertData(db,categories[c].getName()+"",categories[c].getCategory()+"",categories[c].getIconName()+"",categories[c].getScore());
}
//inserting data in table
console.log("success");
} else {
alert("Web SQL Database not supported in this browser");
}
};
function createTable(db) {
try {
db.transaction(function (t) {
t.executeSql(createStatement, []);
});
} catch (e) {
// TODO: handle exception
}
};
function insertData(db, name,category ,iconName,score) {
try {
db.transaction(function (e) {
console.log("start insert");
e.executeSql(insertStatement,[name,category,iconName,score], onSuccess, onError);
});
} catch (e) {
// TODO: handle exception
console.log(e);
}
};
function onSuccess(e) { };
function onError(e) {console.log("erreur insertion"); };
function dropTable(db) {
try {
db.transaction(function (e) {
e.executeSql(dropStatement);
});
} catch (e) {
// TODO: handle exception
}
};
window.onload = function () {
// TODO:: Do your initialization job
Backendless.initApp( APP_ID, SECRET_KEY, VERSION );
fetchingFirstPageAsync();
selectDB();
// add eventListener for tizenhwkey
document.addEventListener('tizenhwkey', function(e) {
if(e.keyName == "back")
try {
tizen.application.getCurrentApplication().exit();
} catch (ignore) {
}
});
navigation("DOWN");
document.addEventListener('keydown', function(e) {
switch(e.keyCode){
case TvKeyCode.KEY_LEFT: //LEFT arrow
break;
case TvKeyCode.KEY_UP: //UP arrow
navigation("UP");
break;
case TvKeyCode.KEY_RIGHT : //RIGHT arrow
break;
case TvKeyCode.KEY_DOWN: //DOWN arrow
navigation("DOWN");
break;
case TvKeyCode.KEY_ENTER: //OK button
go_to(current_item);
console.log("ENTER Button");
break;
default:
console.log("Key code : " + e.keyCode);
break;
}
});
};
function tester(){
console.log("TESTTTTTTT");
};
function navigation(direction){
$("#btn_"+current_item).removeClass("selected_btn");
if(direction == "UP"){
if(current_item == 1)
current_item = total_item;
else
current_item--;
}else if(direction == "DOWN"){
if(current_item == total_item)
current_item = 1;
else
current_item++;
}
$("#btn_"+current_item).addClass("selected_btn");
};
function go_to(current_item){
sessionStorage.setItem("key", current_item);
if(current_item==2)
parent.location="about.html";
if(current_item==1){
console.log("redirection");
parent.location="menu.html";
}
};
function fetchingFirstPageAsync(){
var startTime = (new Date()).getMilliseconds();
var c = Backendless.Persistence.of("CategoriesObject").find();
console.log("============ Fetching first page using the SYNC API ============");
console.log( "Loaded " + c.data.length + "restaurant objects" );
console.log( "Total restaurants in the Backendless storage - " + c.totalObjects);
for(var i = 0; i < c.data.length; i++) {
categories.push(new Category(c.data[i].name+"",c.data[i].iconName+"",c.data[i].score+"",c.data[i].category+""));
console.log(c.data[i].category) ;
}
for (var i in categories) {
console.log(categories[i].getName());
}
console.log("Total time (ms) - " + ((new Date()).getMilliseconds() - startTime ));
};
According to the document, currently the WebSQL is supported in mobile application only.
I tried it in Wearable Gear but it didn't work. It worked in mobile.
main.js
var db;
//database version setting
var version = 1.0;
//database name setting
var dbName = "tizendb";
//database display name setting
var dbDisplayName = "tizen_test_db";
//database size setting
var dbSize = 2 * 1024 * 1024;
function selectDB() {
if (window.openDatabase) {
//openDatabase(name, version, displayname, estimatedsize, callback);
db = openDatabase(dbName, version, dbDisplayName, dbSize);
dropTable(db);
createTable(db);
//inserting data in table
insertData(db, "tizenTest01", "We are pleased to announce that Tizen 2.0");
insertData(db, "tizenTest02", "device vendors. We encourage you to download");
insertData(db, "tizenTest03", "installed and used it. If you have questions");
insertData(db, "tizenTest04", "This release includes many new features");
insertData(db, "tizenTest05", "Highlights of this release include");
dataView(db);
} else {
alert("Web SQL Database is not supported in this browser");
}
}
//reads and displays values from the 'places' table
function dataView(db) {
var html = document.getElementById("tbody01");
var ddlHtml = document.getElementById("ddlTitle");
html.innerHTML = "";
ddlHtml.innerHTML = "";
db.transaction(function (t) {
t.executeSql("SELECT * FROM tizenTable", [],
function (tran, r) {
ddlHtml.innerHTML = "<option value='all'>all</option>";
for (var i = 0; i < r.rows.length; i++) {
var id = r.rows.item(i).id;
var title = r.rows.item(i).title;
var content = r.rows.item(i).content;
var insertday = r.rows.item(i).insertDay;
//data list rendering
if (html) {
html.innerHTML += "<tr><td>" + id + "</td><td>" + title + "</td><td>" + content + "</td><td>" + insertday + "</td></tr>";
}
//select box rendering
if (ddlHtml) {
ddlHtml.innerHTML += "<option value=" + id + ">" + title + "</option>";
}
}
},
function (t, e) { alert("Error:" + e.message); }
);
});
}
// create table
function createTable(db) {
db.transaction(function (t) {
t.executeSql("CREATE TABLE tizenTable (id INTEGER PRIMARY KEY, title TEXT, content TEXT, insertDay DATETIME)", []);
});
}
//inserting data in table
function insertData(db, title, context) {
db.transaction(function (e) {
var day = new Date();
e.executeSql("INSERT INTO tizenTable(title, content, insertDay) VALUES (?, ?, ?)", [title, context, day], onSuccess, onError);
});
}
function onSuccess(e) { }
function onError(e) { }
// drop table
function dropTable(db) {
db.transaction(function (e) {
e.executeSql("DROP TABLE tizenTable");
});
}
//Select the data conditions
function dataChange(value) {
if (value != "all") {
var html = document.getElementById("tbody01");
html.innerHTML = "";
db.transaction(function (t) {
t.executeSql("SELECT * FROM tizenTable WHERE id=?", [value],
function (tran, r) {
for (var i = 0; i < r.rows.length; i++) {
var id = r.rows.item(i).id;
var title = r.rows.item(i).title;
var content = r.rows.item(i).content;
var insertday = r.rows.item(i).insertDay;
if (html) {
html.innerHTML += "<tr><td>" + id + "</td><td>" + title + "</td><td>" + content + "</td><td>" + insertday + "</td></tr>";
}
}
},
function (t, e) { alert("Error:" + e.message); }
);
});
} else {
dataView(db);
}
}
window.onload = function () {
selectDB();
};
Index.html
<thead>
<tr>
<th>id</th>
<th>title</th>
<th>context</th>
<th>date</th>
</tr>
</thead>
<tbody id="tbody01">
</tbody>
I am using SQL adapter and trying to delete row from MYSQL database but i am getting error as worklight.js:5355 Procedure invocation error. Runtime: No value specified for parameter 1. Performed query: delete from customer where id=?
// ******************* SQL Adaptor *****************************
var procedurestat7 = WL.Server.createSQLStatement("delete from customer where id=?");
//preparedStatement.setLong(1, id);
function procedure7(id) {
return WL.Server.invokeSQLStatement({
preparedStatement : procedurestat7,
parameters : [id]
});
}
// ******************** Main.js ***********************************
function wlCommonInit(){
/*
* Use of WL.Client.connect() API before any connectivity to a MobileFirst Server is required.
* This API should be called only once, before any other WL.Client methods that communicate with the MobileFirst Server.
* Don't forget to specify and implement onSuccess and onFailure callback functions for WL.Client.connect(), e.g:
*
* WL.Client.connect({
* onSuccess: onConnectSuccess,
* onFailure: onConnectFailure
* });
*
*/
// Common initialization code goes here
$("#view").load("pages/login.html");
};
function register(){
$("#view").load("pages/register.html");
}
function validateLogin(u,p){
var u = $("#usr").val();
var p = $("#pass").val();
localStorage.setItem('username', u);
var invocationData = {
adapter : 'SQL', // adapter name
procedure : 'procedure4',
parameters : [u,p]
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : loadSQLQuerySuccess, //success callback
onFailure : loadSQLQueryFailure // failure callback
});
function loadSQLQuerySuccess(result){
var data = result.invocationResult;
data = data.resultSet;
console.log(data);
if(data == "" || data == null || data == undefined || data == [] || u == "" || u == " " || u == null || u == undefined || p == "" || p == " " || p == null || p == undefined ){
$("#lgError").show();
console.log('error');
}
else{
console.log(u+" :: "+p);
$("#view").load("pages/data.html");
var uname = localStorage.getItem('username');
console.log(uname);
$("#uname").append(uname);
}
};
function loadSQLQueryFailure(result){
var data = result.invocationResult;
console.log("failed");
};
};
function RegLogin(ru,rp){
var ru = $("#rusr").val();
var rp = $("#rpass").val();
localStorage.setItem('username', ru);
var invocationData = {
adapter : 'SQL', // adapter name
procedure : 'procedure5',
parameters : [ru,rp]
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : rloadSQLQuerySuccess, //success callback
onFailure : rloadSQLQueryFailure // failure callback
});
function rloadSQLQuerySuccess(result){
var data = result.invocationResult;
data = data.resultSet;
if(data == "" || data == null || data == undefined || data == [] ){
alert("User Registered successfully");
$("#view").load("pages/login.html");
}
else{
alert("Error");
}
};
function rloadSQLQueryFailure(result){
var data = result.invocationResult;
$("#rgError").show();
};
};
var invocationData = {
adapter : 'SQL', // adapter name
procedure : 'procedure3'
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : loadSQLQuerySuccess1, //success callback
onFailure : loadSQLQueryFailure1 // failure callback
});
function loadSQLQuerySuccess1(result){
var data = result.invocationResult;
console.log("success");
};
function loadSQLQueryFailure1(result){
var data = result.invocationResult;
console.log("failed");
};
function custTable(){
var custInvokeData = {
adapter:'SQL',
procedure:'procedure6'
}
WL.Client.invokeProcedure(custInvokeData,{
onSuccess: custSuccess,
onFailure: custfailure
});
}
function custSuccess(result){
var data = result.responseJSON;
var isSuccess = data.isSuccessful;
var resultSet = data.resultSet;
console.log(resultSet.length);
console.log('Success Customer Data: '+JSON.stringify(data));
if(isSuccess == true){
console.log('true');
var out = "";
for(var i = 0; i<resultSet.length; i++){
out += "<tr><td>"+resultSet[i].name+"</td><td>"+resultSet[i].des+"</td><td><span class='custid' onclick='deleteData("+resultSet[i].id+")'>X</span></td></tr>";
}
document.getElementById('data').innerHTML = "<table><tr><th>Name</th><th>Desc</th><th>Del</th></tr>" +out+"</table>";
}
else
{
console.log('false');
}
}
function custfailure(result){
var data = result;
console.log('Success Failure Data: '+JSON.stringify(data));
}
function deleteData(id){
console.log('Delete function called');
var id = "";
var custDelData = {
adapter:'SQL',
procedure:'procedure7',
parameter: [id]
}
WL.Client.invokeProcedure(custDelData,{
onSuccess: DelSuccess,
onFailure: Delfailure
});
}
function DelSuccess(){
console.log('deleted');
}
function Delfailure(){
console.log('not deleted');
}
You're supposed to pass an ID value, but in procedure7 you set it as: var id = "" and then pass that as the id... perhaps that is your problem?
function deleteData(id){
console.log('Delete function called');
var id = "";
var custDelData = {
adapter:'SQL',
procedure:'procedure7',
parameter: [id]
}
WL.Client.invokeProcedure(custDelData,{
onSuccess: DelSuccess,
onFailure: Delfailure
});
}
I am trying to implement multiple data insertion on one call and trigger response only after all data is inserted. This is how I am currently doing it:
create: function(req, res) {
var response = {};
var num = req.body.num;
var ret = 0;
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
db.save(function(err){
if(err) {
// Handle error
} else {
ret++;
// Do something
}
});
}
response = {"status" : 200, "message" : "It's working: " + ret};
res.json(response);
}
The problem with this approach is that all the callbacks for save will be triggered after res.json(response) which is wrong because sometimes I would also like to inform user how much data was saved. User will always receive the following response:
It's working: 0
Because ret variable is always 0. It's getting increased only after response is already triggered. What am I doing wrong?
EDIT:
Code after Will's suggestion:
var Q = require('q');
create: function(req, res) {
var response = {};
var num = req.body.num;
var ret = 0;
var tasks = [];
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
tasks.push(db.save());
}
Q.all(tasks).then(
function(results) {
response = {"status" : 200, "message" : "It's working!"};
},
function(err) {
response = {"status" : 500, "message" : "Not working!" };
);
res.json(response);
}
for (var i = 0; i < num; i++) {
var db = new user();
db.enabled = false;
db.save(function(err){
if(err) {
// Handle error
} else {
ret++;
if(ret == num){
response = {"status" : 200, "message" : "It's working: " + ret};
res.json(response);
}
}
});
}
So this will be a lot of code, but what matter is on line 22-25, and line 87-91. The rest of the code works. I have a nested function and want to return the JSON string. Using console.log I can tell it is running properly but will not return the JSON string. Look for the part that says //---------this part-------. There are two parts that I am asking about.
exports.post = function(request, response) {
var mssql = request.service.mssql;
//var data = '{"userID":"ryan3030#vt.edu1"}';
var inputJSON = request.body.JSONtext;
var json = JSON.parse(inputJSON);
var userID = json.userID;
mssql.query("EXEC getMeetingInfo ?", [userID],
{
success: function(results3) {
var meetingsToday = results3.length;
var meetingID = results3[0].meetingID;
var meetingName = results3[0].meetingName;
var meetingDescription = results3[0].meetingDescription;
var meetingLength = results3[0].meetingLength;
var meetingNotes = results3[0].meetingNotes;
var hostUserID = results3[0].hostUserID;
//--------------------------------------THIS PART------------------------------
var JSONfinal = allInfoFunction(mssql, meetingID, userID, meetingName, meetingDescription, meetingLength, meetingNotes, hostUserID, meetingsToday);
console.log(JSONfinal);//DOES NOT WORk
response.send(statusCodes.OK, JSONfinal);//DOES NOT WORK
//---------------------------------BETWEEN THESE----------------------------------
},
error: function(err) {
console.log("error is: " + err);
response.send(statusCodes.OK, { message : err });
}
});
};
function allInfoFunction(mssql, meetingID, userID, meetingName, meetingDescription, meetingLength, meetingNotes, hostUserID, meetingsToday){
mssql.query("EXEC getLocation ?", [meetingID],
{ success: function(results2) {
var meetingLocation = results2[0].meetingLocation;
var JSONlocation = {"meetingLocation": meetingLocation};
mssql.query("EXEC getDateTime ?", [meetingID],
{ success: function(results1) {
var length = results1.length;
var dateTime = [];
dateTime[0] = results1[0].meetingDateTime;
for (var x= 1; x < length; x++) {
dateTime[x] = results1[x].meetingDateTime;
}
//console.log(dateTime);
mssql.query("EXEC getDateTimeVote",
{ success: function(results) {
//console.log(results);
var JSONoutput2 = {};
var JSONtemp = [];
var length2 = results.length;
for(var j = 0; j < length; j++){
var vote = false;
var counter = 0;
for(var z = 0; z < length2; z++){
var a = new Date(results[z].meetingDateTime);
var b = new Date(results1[j].meetingDateTime);
if(a.getTime() === b.getTime()){
counter = counter + 1;
}
if((a.getTime() === b.getTime()) && (results[z].userID == userID)){
vote = true;
}
}
var meetingTimeInput = {"time": b, "numVotes": counter, "vote": vote}
JSONtemp.push(meetingTimeInput);
JSONoutput2.meetingTime = JSONtemp;
}
var JSONfinal = {};
var mainInfoArray = [];
var JSONmainInfo = {meetingID: meetingID, meetingName: meetingName, meetingDescription: meetingDescription, meetingLength: meetingLength, meetingNotes: meetingNotes, hostUserID: hostUserID, meetingLocation: meetingLocation };
JSONmainInfo.meetingTime = JSONtemp;
JSONfinal.numMeetingsToday = meetingsToday;
mainInfoArray.push(JSONmainInfo);
JSONfinal.meetingList = mainInfoArray;
//response.send(statusCodes.OK, JSONfinal);
//---------------------------------------AND THIS PART-------------------------------
console.log(JSON.stringify(JSONfinal));//This outputs the correct thing
var lastOne = JSON.stringify(JSONfinal);
return lastOne; //ths dosent work
//-------------------------------------BETWEEN THESE-----------------------------------
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
},
error: function(err) {
console.log("error is: " + err);
//response.send(statusCodes.OK, { message : err });
}
});
}
I've done a little refactoring to your code to take a more modular approach. It becomes quite tricky to debug something like what you have above. Here it is:
exports.post = function(request, response) {
var mssql = request.service.mssql;
var inputJSON = request.body.JSONtext;
var json = JSON.parse(inputJSON);
var userID = json.userID;
var JSONFinal = {};
getMeetingInfo(userID);
function getMeetingInfo(userID){
mssql.query("EXEC getMeetingInfo ?", [userID], {
success: function(results){
JSONFinal.meetingsToday = results.length;
JSONFinal.meetingID = results[0].meetingID;
JSONFinal.meetingName = results[0].meetingName;
JSONFinal.meetingDescription = results[0].meetingDescription;
JSONFinal.meetingLength = results[0].meetingLength;
JSONFinal.meetingNotes = results[0].meetingNotes;
JSONFinal.hostUserID = results[0].hostUserID;
// Call next function
getLocation(JSONFinal);
},
error: function(err) {
console.log("error is: " + err);
response.send(statusCodes.OK, { message : err });
}
});
}
function getLocation(){
mssql.query("EXEC getLocation ?", [JSONFinal.meetingID], {
success: function(results) {
JSONFinal.meetingLocation = results[0].meetingLocation;
// Call next function
getDateTime(JSONFinal);
},
error: function(err) {
console.log("error is: " + err);
}
});
}
function getDateTime(){
mssql.query("EXEC getDateTime ?", [JSONFinal.meetingID], {
success: function(results) {
var length = results.length;
var dateTime = [];
for (var x= 0; x < length; x++) {
dateTime[x] = results[x].meetingDateTime;
}
// Call next function
getDateTimeVote(dateTime);
},
error: function(err){
console.log("error is: " + err);
}
});
}
function getDateTimeVote(dateTime){
mssql.query("EXEC getDateTimeVote", {
success: function(results) {
var JSONtemp = [];
var length2 = results.length;
for(var j = 0; j < dateTime.length; j++){
var vote = false;
var counter = 0;
for(var z = 0; z < length2; z++){
var a = new Date(results[z].meetingDateTime);
var b = new Date(results1[j].meetingDateTime);
if(a.getTime() === b.getTime()){
counter = counter + 1;
}
if((a.getTime() === b.getTime()) && (results[z].userID == userID)){
vote = true;
}
}
var meetingTimeInput = {"time": b, "numVotes": counter, "vote": vote}
JSONtemp.push(meetingTimeInput);
}
var JSONmainInfo = {
meetingID: JSONFinal.meetingID,
meetingName: JSONFinal.meetingName,
meetingDescription: JSONFinal.meetingDescription,
meetingLength: JSONFinal.meetingLength,
meetingNotes: JSONFinal.meetingNotes,
hostUserID: JSONFinal.hostUserID,
meetingLocation: JSONFinal.meetingLocation
meetingTime: JSONtemp
};
var JSONfinal = {
numMeetingsToday: JSONFinal.meetingsToday,
meetingsList: [JSONmainInfo]
};
// Call next function
sendResponse(JSON.stringify(JSONfinal));
},
error: function(err) {
console.log("error is: " + err);
}
});
}
function sendResponse(data){
response.send(statusCodes.OK, data);
}
};
It looks a lot different but the functionality is pretty much the same. The key point if you look at the code is that each subsequent function is executed only after the success of the previous function. This effectively chains the methods together so that they are always executed in order and is the key point of difference.
One thing to note here is the similarity between your
allInfoFunction(...
and my
getMeetingInfo(userID)
Both of these will return undefined more or less immediately, after the MSSQL query is sent to the server. This is because the request is fired asynchronously, and the javascript continues to run through the code. After it's fired of the asynchronous request, it has nothing left to do in that function, so it returns. There is no return value specified so it returns nothing (or undefined if you will).
So all in all, the code in the question code will return undefined and then attempt to send a response before anything has actually happened. This code fixes that problem by firing the sendResponse after all the queries have been executed.
I refactored this code in a text editor and haven't run it, or checked it for errors, so follow the basic outline all you like but it may not be a good idea to copy and paste it without checking it's not broken