I have this sqlite query in a angularjs app.
$scope.testArr = [];
$scope.testFunk = function(){
var db = window.openDatabase("test", "1.0", "Test DB", 1000000);
db.transaction(function(tx){
tx.executeSql('SELECT * FROM EVENTS',
[],
//Callback function with transaction and
//results objects
function(tx, results){
//Count the results rows
var rowsCount = results.rows.length;
//Loop the rows
for (var i = 0; i < rowsCount; i++){
//Build a results string, notice the
//column names are called
$scope.testArr.push({
id: results.rows.item(i).eventId,
nameSel: results.rows.item(i).eventNameSel,
name: results.rows.item(i).eventName,
eventDesc: results.rows.item(i).eventDesc,
eventUrl: results.rows.item(i).eventUrl,
time: results.rows.item(i).eventTime
})
}
console.log($scope.testArr);
},
errorHandler);
});
}
//
The console.log returns the right objects, but If I do a console.log outside of the db.transaction function it returns empty. The problem is that I want to call the $scope.testFunk() function and return the result from the query to a variable which I then can process further, like:
var result = $scope.testFunk();
console.log(result);
// prints results from query.
I suggest you to use a service.
The reason it's not working now is because when you trying to print the results, it's still not populated. you can add $watch over results and work with it when it's populated.
$scope.testFunk(); // modify $scope.results within the function
$scope.$watch('results', function(resultsNewVal, resultsOldVal) {
console.log(resultsNewVal);
}
Related
I want to store all the rows from table to array(arr), I need to get the stored array outside of the defined query section. Is there a way I can get all the rows outside db.each such that I can manipulate them further.
var arr=[];
db.each("SELECT * FROM login", function(err, row) {
var title=row.title;
var context=row.context;
var newItem = {
'user': user,
'pwd': pwd
};
arr.push(newItem);
});
console.log(arr); //Outputs []
Because db.each is an asynchronous function, you need to use another function as a callback, like:
var arr=[];
db.each("SELECT * FROM login", function(err, row) {
var title=row.title;
var context=row.context;
var newItem = {
'user': user,
'pwd': pwd
};
arr.push(newItem);
}, function(){
console.log(arr)
});
Reference: https://github.com/mapbox/node-sqlite3/wiki/API#databaseeachsql-param--callback-complete
DEMO
I am unable to retrieve third value of the row it is showing undefined when displayed using alert box .What i am basically trying to achieve is insert 4 rows to table and retrieve them as required sorted based on a column
HTML
<div id="status" name="status">Status Message</div>
Javascript
var db = openDatabase('mydb', '1.0', 'Test DB', 4 * 1024 * 1024);
var msg;
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS LOGS (id unique, log Text,log1 Text)');
tx.executeSql('INSERT INTO LOGS (id, log,log1) VALUES (1, "foobar","sa")');
tx.executeSql('INSERT INTO LOGS (id, log,log1) VALUES (2, "logmsg","da")');
msg = '<p>Log message created and row inserted.</p>';
document.querySelector('#status').innerHTML = msg;
});
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM LOGS', [], function (tx, results) {
var len = results.rows.length,
i;
msg = "<p>Found rows: " + len + "</p>";
document.querySelector('#status').innerHTML += msg;
for (i = 0; i < len; i++) {
msg = "<p><b>" + results.rows.item(i).log + "</b></p>";
document.querySelector('#status').innerHTML += msg;
var book = results.rows.item(i);
console.log(book);
alert(book.log1);
}
}, null);
});
here i make something very similar to yours, and here it's working. Here my Ids are like:
id integer primary key
So when I do an insert, I don't have to use them, I let web sql take care of it
tx.executeSql('INSERT INTO LOGS (log,log1) VALUES ("logmsg","da")');
Also, I use promises (the code bellow is using angularJs
self.query = function(query, bindings) {
bindings = typeof bindings !== 'undefined' ? bindings : [];
var deferred = $q.defer();
self.db.transaction(function(transaction) {
transaction.executeSql(query, bindings, function(transaction, result) {
deferred.resolve(result);
}, function(transaction, error) {
deferred.reject(error);
});
});
return deferred.promise;
};
self.fetchAll = function(result) {
var output = [];
for (var i = 0; i < result.rows.length; i++) {
output.push(result.rows.item(i));
}
return output;
};
self.fetch = function(result) {
return result.rows.item(0);
};
So I can use it this way:
return DB.query('SELECT * FROM registro WHERE dia = ? and mes = ? and ano = ? order by horario', [dia, mes, ano])
.then(function(result){
return DB.fetchAll(result);
});
I hope this can get you some directions...
Your DEMO link works fine for me (with Chrome 39) - I'm getting 'sa', 'da' alerts after running it. So I think it's something specific to your browser or more probably your cache.
Have you maybe created LOG table without the log1 column at first? Maybe it's still stored in your browser, because
CREATE TABLE IF NOT EXISTS LOGS (id unique, log Text,log1 Text)
line is not going to override it.
In Chrome you can check WebSQL schema hold by the browser with ChromeDevTools and 'Resources' tab, take a look there and see if mydb/LOGS table have your log1 column and data in it.
I've made a function myFunction which performs simple task i.e. to retrieve data from sqlite database and save it in a array which can be used easily. This function should follow these steps to fulfill my functionality.
To retrieve data from database.
To save it into array.
return array
But it is performing these steps in this sequences; 3, 1, 2, so I am not getting the data because it returns without getting it.
e.g.
function myFunction() {
var ret;
var arr = [];
db.transaction(function (trans) {
trans.executeSql('SELECT * FROM tblname', [],
function (transaction, result) {
if (result != null && result.rows != null) {
for (var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
ret = row.urlcolmn;
arr.push(ret);
alert('alert 1'); // just to check which line(alert) is called first
}
}
}, errorHandler);
}, errorHandler, nullHandler);
alert('alert 2'); // just to check which line(alert) is called first
return arr;
}
In above code alert 2 is shown before alert 1..... that's why it doesn't return value in array. This problem can be because sqlite in JS is Asynchronous.
I m creating mobile web application using html5 and javascript.I m having two javascript files. AttributesDatabase.js and AttributeView.js.From AttributeView.js i m calling one function from AttributeDatabase.js in that i m executing one select query.Now the query result should go to AtttributeView.js.But the Websql transaction is asynchronous call that is what it is not returning proper result.Is there any way to handle the websql result.
Please help if any way there?
Edited
AttributeView.js
var AttributeDAOObj = new AttributeDAO();
AttributeDAOObj.GetAttributeList();
alert(AttributeDAOObj.GetAttributeList()); //This alert is coming as undefined.
AttributeDAO.js
this.GetAttributeList = function () {
var baseDAOObj = new BaseDAO();
var query = "SELECT AttributeName FROM LOGS";
// this.Successcalbackfromsrc = this.myInstance.Successcalback;
var parm = { 'query': query, 'Successcalback': this.myInstance.Successcalback };
baseDAOObj.executeSql(parm);
}
//To Create database and execute sql queries.
function BaseDAO() {
this.myInstance = this;
//Creating database
this.GetMobileWebDB = function () {
if (dbName == null) {
var dbName = 'ABC';
}
var objMobileWebDB = window.openDatabase(dbName, "1.0", dbName, 5 * 1024 * 1024);
return objMobileWebDB;
}
//Executing queries and getting result
this.executeSql = function (query) {
var objMobileWebDB = this.myInstance.GetMobileWebDB();
objMobileWebDB.transaction(function (transaction) {
//In this transaction i m returning the result.The result value is coming.
transaction.executeSql(query, [], function (transaction, result) { return result; }, this.Errorclback);
});
}
}
The problem is in you succes call back (like in the comment to your question, stated by DCoder)
function (transaction, result) { return result; }
this is returning where to?
So this is how to do it (or at least one way)
you can do for example:
function (transaction,result){
console.log("yes, I have some result, but this doesn't say anything, empty result gives also a result");
// so check if there is a result:
if (result != null && result.rows != null) {
if (result.rows.length == 0) {
// do something if there is no result
}else{
for ( var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
var id = result.rows.item(i).id; //supposing there is an id in your result
console.log('Yeah! row id = '+id);
}
}
}else{
// do something if there is no result
}
};
note the code above can be compacter, but this is how to understand it better.
another way is to put this function is a seperate piece of code, so you keep the sql statement more compact and readable. Like you call you error callback this can be in your function (with this. in front of it) or a completely seperate function.
I am using the following code
var Year12=new Array();
GetYear(function(Year12)
{
alert(Year12);
});
function GetYear(callback)
{
var selectAllStatement = "SELECT DISTINCT year FROM mytable";
var db = openDatabase("Postit", "1.0", "Notebook", 200000);
var dataset;
alert("1");
db.transaction(function(tx) {
alert("2");
tx.executeSql(selectAllStatement, [], function(tx, result)
{
alert("3");
dataset = result.rows;
for (var i = 0, item = null; i < dataset.length; i++)
{
item = dataset.item(i);
Year12[i]=item['year'];
}
callback(Year12);
});
});
}
Here the tx.executeSql statements are not getting executed means alert 3 is not displaying.Is there any way to do this
The db.transaction and tx.executeSql calls are asynchronous, hence the callback functions. That means that GetYear will finish executing and return before the tx.executeSql callback will populate your Year12 array.
Once you have asynchronous behavior and callbacks, the only sensible solution is, of course, more callbacks. You need a structure more like this:
function GetYear(callback) {
//...
db.transaction(function(tx) {
//...
tx.executeSql(selectuniqueyearStatement, [], function(tx, result) {
var Year12 = [ ];
//... populate the locale Year12 using result.rows
callback(Year12);
});
});
}
and then use it like this:
GetYear(function(year12) {
// Do whatever you need to do with the year12 array...
});
Basically the same code structure and strategies that you use with AJAX calls.