When below Sample code of Phonegap app is executed in iPad, table gets created as well as records get inserted. But as soon as it navigates to next page using "window.location = 'main.html'" table disappears/delete. Some time it works properly and all records get displayed on main.html. Sample code:
db.transaction(function (transaction) {
transaction.executeSql('drop table if exists categoryType', null, function () {
transaction.executeSql('create table if not exists categoryType(id text primary key, code text, name text)', null, function () {
for (var i = 0; i < category_types.length; i++)
{
var insert_count = 0;
transaction.executeSql('insert into categoryType(id, code, name) values(?,?,?)', [category_types[i].id, category_types[i].code , category_types[i].name],
function()
{
insert_count++;
if ( insert_count == category_types.length)
window.location = "main.html";
});
}
});
});
});
If we add timeout in above code before navigating to main.html page issue gets resolved.
Sample code with timeout:
db.transaction(function (transaction) {
transaction.executeSql('drop table if exists categoryType', null, function () {
transaction.executeSql('create table if not exists categoryType(id text primary key, code text, name text)', null, function () {
for (var i = 0; i < category_types.length; i++)
{
var insert_count = 0;
transaction.executeSql('insert into categoryType(id, code, name) values(?,?,?)', [category_types[i].id, category_types[i].code , category_types[i].name],
function()
{
insert_count++;
if ( insert_count == category_types.length)
{
setTimeout(function() {
window.location = "main.html";
}, 5000);
}
});
}
});
});
});
I can run the code successfully using a timeout, but I don't want to depend on arbitrary timeout period. Earlier the same code was working properly but now it is causing issue recently. Is there any solution??
Related
I need help with this, I really can't crack this one up.
I have this web site using Node.js to call mySQL queries and display them as tables, each in it's own page. To do so, I created 4 objects that include a name, a title and the query. when I have this code going four times (from queryPage[0] to queryPage[3]), It works great. But i want to put it into a for loop so I won't need 4 repetitions of the same lines, but then it doesn't work. the pages don't load... Any idea what is going on?
connection.query(queryPage[0].query, function(err, rows) {
var arr = [];
for (var i in rows) {
arr[i] = rows[i];
}
app.get('/' + queryPage[0].name, function(req, res) {
res.render('pages/' + queryPage[0].name, {
title: queryPage[0].title,
data: arr
});
});
});
I think you need something more like this
var queryPage = [ ... ];
// This route catches all request
app.get('/:name', function (req, res, next) {
// :name = req.params.name
var page;
for(var i = 0, l = queryPage.length; i < l; i++)
if(queryPage[i].name === req.params.name) {
page = queryPage[i];
break;
}
// Check the page exists
if(!page) return res.status(404).send('Not found');
// if(!page) return next();
connection.query(page.query, function(err, rows) {
res.render('pages/' + page.name , {
title: page.title,
data: rows
});
});
});
I am trying to query, foreach id in an array, some data from the MySQL database.
My for loop looks like the following
for(var i = 0; i < res.length; i++) {
var steamid = res[i].steamid;
db.query('SELECT `name` FROM `users` WHERE `steamid`=?', [steamid], function(err, rows) {
var player = {name: rows[i].name};
team.push(player);
});
}
But the problem is that the for loop continues before the query is finished and then the var i is already increased by one or two.
Is there a way to check if the query has finished?
Just use a closure so that your i refers to the correct index.
function finished(){...}//called when you fetched all your data
var nbDone = 0;
res.forEach(function(elem, i){
var steamid = elem.steamid;
db.query('SELECT `name` FROM `users` WHERE `steamid`=?', [steamid], function(err, rows) {
var player = {name: rows[i].name};
team.push(player);
nbDone++;
if(nbDone == res.length){
finished();//you know all of your queries have completed
}
});
});
you may want to have a look at promises or async in order to handle your asynchronous flows
I am running a simple program for long polling to check if any change happens in database to send it to browser in Node.js. I know how to use the callback function but I need to return a value from program.query function to be returned because I will use it in the recursive function. Thanks for your help.
var server=http.createServer(function(req,res){
program.run(res, 5);
});
server.on('listening',function(){
console.log('ok, server is running');
});
server.listen(9000);
var program = {
run: function(res, id, old){
if(old == undefined){
// I need a value from database to be returned to old variable
old = program.query(res, id /*, function(){res.end('there') }*/);
}
clearTimeout(tt);
var tt = setTimeout( function(){
// I need a value from database to be returned to new_ variable
var new_ = program.query(res, id /*, function(){res.end('there') }*/);
if(new_ != old){
// ... Send Response with the change to browser
}
else{ // no change in database, so run again
old = new_;
program.run(res, id, old);
}
}, 2000);
},
query: function(res, id /*,callback*/){
connection.query('SELECT table1.column1 FROM table1 WHERE table1.id ="'+id+'"', function(err, rows, fields){
//callback(res,id,rows[0].column1); // I don't want this solution
return rows[0].column1; // Not working..
});
}
};
Just call it recursively in the callback. It looks exactly what it sounds like:
var program = {
run: function(res, id, old){
if(old == undefined){
program.query(res, id , function(res,id,result){
old = result;
clearTimeout(tt);
var tt = setTimeout( function(){
program.query(res, id , function(res,id,new_){
if(new_ != old){
// ... Send Response with the change to browser
}
else{ // no change in database, so run again
old = new_;
program.run(res, id, old);
}
// not sure where you want to put the res.end()
// since I don't really know your logic.
});
}, 2000);
});
}
else {
// This code is of course identical to the code above
// so you can refactor it out into its own function.
clearTimeout(tt);
var tt = setTimeout( function(){
program.query(res, id , function(res,id,new_){
if(new_ != old){
// ... Send Response with the change to browser
}
else{ // no change in database, so run again
old = new_;
program.run(res, id, old);
}
// not sure where you want to put the res.end()
// since I don't really know your logic.
});
}, 2000);
}
},
query: function(res, id, callback){
connection.query('SELECT table1.column1 FROM table1 WHERE table1.id ="'+id+'"', function(err, rows, fields){
callback(res,id,rows[0].column1);
});
}
};
I'm leveraging Google Chrome's omnibox API in my extension.
Current users, including myself, have noticed that the omnibox ceases responding entirely after an undetermined state change or a period of time lapsing. Typing the word to trigger entering into "omnibox" stops having any effect and the URL bar does not shift into omnibox mode.
Restarting Google Chrome does not fix the issue, but restarting my plugin by unchecking and then re-checking the 'enabled' checkbox on chrome://extensions does resolve the issue.
Does anyone have any suggestions on what to investigate? Below is the code used. It is only loaded once through my permanently persisted background page:
// Displays streamus search suggestions and allows instant playing in the stream
define([
'background/collection/streamItems',
'background/model/video',
'common/model/youTubeV2API',
'common/model/utility'
], function (StreamItems, Video, YouTubeV2API, Utility) {
'use strict';
console.log("Omnibox LOADED", chrome.omnibox);
var Omnibox = Backbone.Model.extend({
defaults: function () {
return {
suggestedVideos: [],
searchJqXhr: null
};
},
initialize: function () {
console.log("Omnibox INITIALIZED");
var self = this;
chrome.omnibox.setDefaultSuggestion({
// TODO: i18n
description: 'Press enter to play.'
});
// User has started a keyword input session by typing the extension's keyword. This is guaranteed to be sent exactly once per input session, and before any onInputChanged events.
chrome.omnibox.onInputChanged.addListener(function (text, suggest) {
// Clear suggested videos
self.get('suggestedVideos').length = 0;
var trimmedSearchText = $.trim(text);
// Clear suggestions if there is no text.
if (trimmedSearchText === '') {
suggest();
} else {
// Do not display results if searchText was modified while searching, abort old request.
var previousSearchJqXhr = self.get('searchJqXhr');
if (previousSearchJqXhr) {
previousSearchJqXhr.abort();
self.set('searchJqXhr', null);
}
var searchJqXhr = YouTubeV2API.search({
text: trimmedSearchText,
// Omnibox can only show 6 results
maxResults: 6,
success: function(videoInformationList) {
self.set('searchJqXhr', null);
var suggestions = self.buildSuggestions(videoInformationList, trimmedSearchText);
suggest(suggestions);
}
});
self.set('searchJqXhr', searchJqXhr);
}
});
chrome.omnibox.onInputEntered.addListener(function (text) {
// Find the cached video data by url
var pickedVideo = _.find(self.get('suggestedVideos'), function(suggestedVideo) {
return suggestedVideo.get('url') === text;
});
// If the user doesn't make a selection (commonly when typing and then just hitting enter on their query)
// take the best suggestion related to their text.
if (pickedVideo === undefined) {
pickedVideo = self.get('suggestedVideos')[0];
}
StreamItems.addByVideo(pickedVideo, true);
});
},
buildSuggestions: function(videoInformationList, text) {
var self = this;
var suggestions = _.map(videoInformationList, function (videoInformation) {
var video = new Video({
videoInformation: videoInformation
});
self.get('suggestedVideos').push(video);
var safeTitle = _.escape(video.get('title'));
var textStyleRegExp = new RegExp(Utility.escapeRegExp(text), "i");
var styledTitle = safeTitle.replace(textStyleRegExp, '<match>$&</match>');
var description = '<dim>' + video.get('prettyDuration') + "</dim> " + styledTitle;
return {
content: video.get('url'),
description: description
};
});
return suggestions;
}
});
return new Omnibox();
});
As far as I'm aware the code itself is fine and wouldn't have any effect on whether I see omnibox or not.
You can find full source code here: https://github.com/MeoMix/StreamusChromeExtension/blob/master/src/js/background/model/omnibox.js
I'm making a database application for Safari purely. So I'm following this guide made by Apple: Link.
I have made this "class" prototype so far. It works, but it keeps making duplicates of the database (they just keep stacking up in the Safari Inspector tool) (without me changing the version from 1.0):
function Database() {
this.DB = null;
this.shortName = 'gamedb';
this.version = '1.0';
this.displayName = 'Database';
this.maxSize = 5 * 1024 * 1024;
init: (function() {
})
this.initDB = function() {
try {
if (!window.openDatabase) {
alert('Error: Databases are not supported.');
}
else {
this.DB = openDatabase(this.shortName, this.version, this.displayName, this.maxSize);
}
return true;
}
catch(e) {
if (e == 2) {
// Version number mismatch.
console.log("Error: Invalid database version.");
}
else {
console.log("Error: Unknown, " + e + ".");
}
return;
}
}
this.query = function(query) {
if (query == undefined) {
query = '';
}
query = query + ';'; // Add the ending semi-colon
this.DB.transaction(
function (transaction) {
transaction.executeSql(
query,
[],
this.nullDataHandler,
this.errorHandler
);
}
);
}
this.nullDataHandler = function() {
return 0;
}
this.errorHandler = function(error) {
return 0;
}
}
And here's my main.js file with my jQuery handle and the instantiation of the Database prototype:
$(document).ready(function() {
var DB = new Database();
DB.initDB();
DB.query('CREATE TABLE IF NOT EXISTS users(id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)');
DB.query('INSERT INTO users(name) VALUES ("Jackson")');
});
Even just blankly running this line creates duplicates:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>X</title>
<style>
html, body {
background: #202020;
color: #8d9d6a;
}
</style>
<script type="text/javascript">
var shortName = 'mydatabase';
var version = '1.0';
var displayName = 'My Important Database';
var maxSize = 65536; // in bytes
var db = openDatabase(shortName, version, displayName, maxSize);
</script>
</head>
<body>
Content
</body>
</html>
Notes:
I have Extensions turned off
No changes in the Developer menu (nothing disabled or blocked)
I had this problem in both chrome and safari. When I saved a record it would appear several times and the inspector would show duplicates of the webSQL db (50 or more!). For me it turned out that I was calling a SELECT too soon after the save in order to update the view. I moved it into a success function and that fixed the problem. I can only think that the browser gets confused and spawns multiple DBs in the inspector. This might not be the same problem but it seemed close enough to mention.
Side information for anyone as new to this as myself.
I had a query selecting from more than one table which caused my display to duplicate. Stupid problem, simple fix by obviously selecting a single table
var showLearnerSQL = "SELECT * FROM tblLearnerInfo, tblDrive";// Not a great idea
var showLearnerSQL = "SELECT * FROM tblLearnerInfo; // Great idea