SaveData.js
function queryDB(callback) {
var sqlTxt = "SELECT * FROM DEMO";
db.transaction(
function(tx) {
tx.executeSql(sqlTxt, [],
function(tx, results) {
var item_Codes = [];
for (var i = 0; i < results.rows.length; i++) {
item_Codes.push({item_code: results.rows.item(i).itemCode});
}
callback(item_Codes);
})
, errorCB;
});
return false;
}
main.js
queryDB();
console.log( item_Codes);
I have above two methods to retrieve data from database .It works fine but i need to combine these two methods to one method and return the itemCodes array.
var processResult = function(items)
{
//process returned array 'items'
}
function queryDB(callback) {
var sqlTxt = "SELECT * FROM DEMO";
db.transaction(
function(tx) {
tx.executeSql(sqlTxt, [],
function (tx, results) {
var item_Codes = [];
for (var i = 0; i < results.rows.length; i++) {
item_Codes.push({item_code: results.rows.item(i).itemCode});
}
callback(item_Codes);
})
, errorCB);
});
return false;
}
and call it with:
queryDB(processResult);
or you can use global variable item_Codes instead of function processResult
Related
I'm a newbie in javascript and node js. I actually want to compare two data based on MySQL value.
what I want to do is Loop for the pair of data -> get value from db -> concat pair of data and value -> endloop
Here's my code
routes/masterdata.js
var Masterdata = require('../models/Masterdata');
var outputFile = {}
for (var i = 0; i < dataFile.length; i++) {
if (dataFile[i]['existing'] != null) {
for (var x = 0; x < dataFile.length; x++) {
var param = {
tech_row: dataFile[i]['existing'],
tech_col: dataFile[x]['new']
};
Masterdata.compareData(param, function(err, rows) {
console.log(rows);
outputFile.push({
value: rows
});
});
}
}
}
console.log(outputFile);
models/Masterdata.js
var Masterdata = {
compareData: function(param, callback) {
return db.query('SELECT value FROM sod_matrix WHERE TECH_NAME_ROW = ? AND TECH_NAME_COL = ?', [param.tech_row, param.tech_col], callback);
}
}
My Question is how to populate data from function compare data into an array in the loop?
var Promise = require('bluebird');
var completed=[];
var Masterdata = require('../models/Masterdata');
var outputFile = []; //should be an array
for (var i = 0; i < dataFile.length; i++) {
if (dataFile[i]['existing'] != null) {
for (var x = 0; x < dataFile.length; x++) {
var param = {
tech_row: dataFile[i]['existing'],
tech_col: dataFile[x]['new']
};
completed.push(new Promise(resolve, reject){
Masterdata.compareData(param, function(err, rows) {
if(err)
{
reject(err);
}
else
{
console.log(rows);
outputFile.push(rows); //that;s pretty enough
resolve();
}
});
});
}
}
}
Promise.all(completed)
.then((res)
{
console.log(outputFile);
});
I have a series of nested async calls that need to finish before my code continues. Function save_part1 calls the sqlite database and returns the rows of interest. For each of those rows, I make an ajax call to a save them remotely.
From what I have read about promises and deferred, I have only seen them being used in the context of ajax calls. And on top of that, it makes my brain hurt.
Question: how do I wait until all the ajax calls have completed before starting save_part2?
function save()
{
save_part1();
//this should only happen after all the ajax calls from save_part1 are complete
save_part2();
}
function save_part1()
{
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE1", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++)
{
var row = results.rows.item(i);
ajaxCall_item1(row);
}
}, errorHandler)
});
}
function save_part2()
{
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE2", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++)
{
var row = results.rows.item(i);
ajaxCall_item2(row);
}
}, errorHandler)
});
}
As long as you have ajaxCall_item returning the jQuery deferred object, you can have save_part1 return a deferred object, collect the returned promises into an array, call them with $.when and resolve the "promise" once all of the requests have completed. Then you will be able to write: save_part1().then(save_part2);. Here is an untested example:
function save() {
save_part1().then(save_part2).fail(function(err) {
// ohno
});
}
function ajaxCall_item1(row) {
return $.ajax({ ... });
}
function save_part1()
{
var dfd = jQuery.Deferred();
var promises = [];
db.transaction(function (tx) {
tx.executeSql("SELECT * FROM TABLE1", [],
function (transaction, results) {
for (var i = 0; i < results.rows.length; i++) {
var row = results.rows.item(i);
promises.push(ajaxCall_item1(row));
}
$.when.apply($, promises).then(function() {
dfd.resolve.apply(dfd, arguments);
});
}, function(err) {
dfd.reject(err);
});
});
return dfd;
}
I'm trying to use Phonegap function executeSql to fetch a SQL Query with a select statement , i'm just want to return a query results from my OOP function
i read this question
Return executeSQL function
but i can't undrestand it well so i can't apply it on my code
function Invoice() {
this.read = function(){
var stmnt = "SELECT * FROM invoices ORDER BY ID DESC";
function callback(callback_fun){
var myrows = [];
db.transaction(function(tx){
tx.executeSql(stmnt, [], function(tx,result){
for(var i = 0; i < result.rows.length; i++){
var row = result.rows.item(i);
myrows.push(row);
}
//console.log(myrows);
callback_fun(myrows);
}, function(tx,error){
alert('Error: '+error.message);
return;
});
});
}
callback(function(newResult){
return newResult;
});
};
};
var newInvoice = new Invoice();
var myResult = newInvoice.read();
alert(myResult);
You need to set your callback() plus callback_fun() as an return value like this:
function Invoice() {
this.read = function(){
var stmnt = "SELECT * FROM invoices ORDER BY ID DESC";
function callback(callback_fun){
var myrows = [];
db.transaction(function(tx){
tx.executeSql(stmnt, [], function(tx,result){
for(var i = 0; i < result.rows.length; i++){
var row = result.rows.item(i);
myrows.push(row);
}
//console.log(myrows);
return callback_fun(myrows); // <<----- RETURN
}, function(tx,error){
alert('Error: '+error.message);
return;
});
});
}
return callback(function(newResult){ // <<<<<<<<----------- RETURN
return newResult;
});
};
};
What Javascript Callstack looks like:
you are calling Invoice.read(), but read-Function has no return keyword so it doesn't return anything, what leads to undefined
You are calling your callback function. Which also returns nothing.
EDIT2:
Oh ok you are invoking another function db.transaction which currently returns the value to your callback function. So you could probably do that:
function callback(callback_fun){
var myrows = [];
return db.transaction(function(tx){
tx.executeSql(stmnt, [], function(tx,result){
for(var i = 0; i < result.rows.length; i++){
var row = result.rows.item(i);
myrows.push(row);
}
//console.log(myrows);
return callback_fun(myrows); // <<----- RETURN
}, function(tx,error){
alert('Error: '+error.message);
return;
});
});
}
EDIT:
This is your code. Oh Well a little bit simplified: JSBIN
This is my code. JSBIN-Working Example
You need to press Run with JS in the right corner.
How to retrieve an array of data arrMyLatLng function.
db.transaction(queryDB, errorCB);
function queryDB(tx)
{
tx.executeSql('SELECT * FROM Attractions', [], querySuccess, errorCB);
}
function querySuccess(tx, results)
{
var arrMyLatLng = [];
var len = results.rows.length;
var arrLatitude=[], arrLongitude=[];
for (var i=0; i<len; i++)
{
arrLatitude[i] = results.rows.item(i).latitude;
arrLongitude[i] = results.rows.item(i).longitude;
arrMyLatLng[i] = new google.maps.LatLng(arrLatitude[i], arrLongitude[i]);
}
return arrMyLatLng ; // Need this array to manipulate the data from it is outside of the function.
}
Thanks
You're performing an asynchronous operation which will execute its callback whenever the operation completes. Hence there is nothing that you can return arrMyLatLng to. All work with arrMyLatLng will need to be done in the callback. One thing you can do is call another function from querySuccess and pass arrMyLatLng to it:
function querySuccess(tx, results) {
var arrMyLatLng = [];
var len = results.rows.length;
var arrLatitude=[], arrLongitude=[];
for (var i=0; i<len; i++) {
arrLatitude[i] = results.rows.item(i).latitude;
arrLongitude[i] = results.rows.item(i).longitude;
arrMyLatLng[i] = new google.maps.LatLng(arrLatitude[i], arrLongitude[i]);
}
someOtherFunction(arrMyLatLng);
}
I am fairly certain this is a ten penny closure question. But having read a few articles on closures, I still cannot get this to work.
character is always returned as 'Z'. character is also a global variable.
I need "render" to remember the character in the loop:
populateList: function()
{
var render = function(tx, result)
{
console.log(character);
for (var i = 0; i < result.rows.length; i++)
{
var contact = result.rows.item(i);
console.log(contact.Name);
}
}
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(var i = 0; i < str.length; i++)
{
var nextChar = str.charAt(i);
database.open();
var sql = "SELECT Name FROM Contact WHERE Name LIKE \'" + nextChar + "%\' ORDER BY Name";
database.query(sql, render);
}
}
var render = function(character)
{
return function(tx, result)
{
console.log(character);
for (var i = 0; i < result.rows.length; i++)
{
var contact = result.rows.item(i);
console.log(contact.Name);
}
}
}
Usage:
database.query(sql, render(nextChar));
Edit:
Also, asawyer is correct in his comment above -- assuming you are using node-mysql, it has support for parameterized queries:
database.query("SELECT * FROM foo WHERE bar = ?", [ 1 ]);
Use that and save yourself some trouble!
Untested:
populateList: function()
{
var render = function(char)
{
console.log(char);
return function(tx, result) {
for (var i = 0; i < result.rows.length; i++)
{
var contact = result.rows.item(i);
console.log(contact.Name);
}
};
}
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for(var i = 0; i < str.length; i++)
{
var nextChar = str.charAt(i);
database.open();
var sql = "SELECT Name FROM Contact WHERE Name LIKE \'" + nextChar + "%\' ORDER BY Name";
database.query(sql, render(nextChar));
}
}
Use an immediately executing function that returns a function that calls render with the parameters:
database.query(sql, (function(nextChar) {
return function(tx, result) {
return render(tx, result, nextChar);
};
})(nextChar));
Then add the appropriate nextChar parameter to render, too.
var render = function(tx, result)
{
console.log(character);
***var char = character;***
for (var i = 0; i < result.rows.length; i++)
{
var contact = result.rows.item(i);
***console.log(char);***
console.log(contact.Name);
}
}
i guess this is what you need. add the highlighted lines. cheers