Updating SQLite with AJAX data: how to handle two asynchronous calls - javascript

I'm trying to update SQLite with some JSON data fetched via AJAX.
This is my progress so far.
The problem is that this function always returns false. I know that this is because of the second asynchronous execution of the db.transaction. How can I solve this?
Thanks in advance!
function updateDb(url) {
$.ajax({url: url,
type: "get",
dataType: "jsonp",
async: true,
success: function (result) {
ajax.parseJSONP(result);
},
error: function (request,error) {
console.error('Network error while fetching IR JSON!');
}
});
var ajax = {
parseJSONP:function(result){
var db = window.openDatabase("Test", "1.0", "Test DB", 100000);
db.transaction(populateDB, errorCB, successCB);
function populateDB(tx) {
tx.executeSql('DROP TABLE IF EXISTS testtable;');
tx.executeSql('CREATE TABLE IF NOT EXISTS testtable (id NUMERIC PRIMARY KEY, testtext TEXT)');
$.each( result, function(i, row) {
tx.executeSql('INSERT INTO testtable (id, testtext) VALUES (' + row[0] + ',\'' + row[1] + '\';');
});
}
function errorCB(err) {
console.error("Error processing SQL: "+err.message);
return false;
}
function successCB() {
console.info("Updating DB successful!");
return true;
}
}
}
}

Ok, I solved this by using two callbacks, one to parseJSONP and one to the success callback.
I think this is a valid solution, however, I really hate navigating only by callbacks.

Related

Parse server query each with useMasterKey parameter

I'm migrating from Parse to Parse server. Most of my code is made without promises.
For this to work, I have to send the parameter: useMasterKey: true (where necessary) for each query / save.
For find and get queries or fetch objects, I have no problems, example:
Parse.com (find)
query.find({
success: function(results) {
//...
Parse Server (find)
query.find({useMasterKey: true
}).then(function(results) {
//....
Parse.com (fetch)
user.fetch({
success: function(user) {
//...
Parse Server (fetch)
user.fetch({useMasterKey: true,
success: function(user) {
//....
The problem is with each functions:
Parse.com (each)
query.each(function(comment) {
//...
Parse Server (each)
query.each({useMasterKey: true
}).then(function(comment) {
//....
It does not work.
Thanks
Although the docs don't suggest that the useMasterKey option is supported for an each query, having tested and verified myself it is in fact possible. Syntax as follows:
query.each(callback, {useMasterKey: true})
Where callback is a function that is called for each result of the query.
The each method of a query support useMasterKey, it's passed as an argument after the callback function, that will be executed for each result of the query.
The syntax is:
query.each(function (object, error) {
// Your function code
}, {
useMasterkey: true
})
Where object is a result for the query and error is a possible error that happened.
But, as shown here, it's better to just use useMasterKey for when you're actually changing something in the database:
query.each(function (object, error) {
object.destroy({
success: function (object) {
console.log("Successfully destroyed object.")
},
error: function (error) {
console.log("Error: " + error.code + " - " + error.message)
},
useMasterKey: true
})
})

How to wait a in a for loop until ajax call finishes

I'm new to developing web sites and I'm developing a small web site. Here I'm using ajax to show new comments. this is the function I wrote
function show_comments() {
$('div#P_all_posts>div').each(function () {
id = this.id.replace("post", "");
$.ajax({
url: 'http://localhost/seppro/index.php/group/show_comments',
type: 'post',
data: {
id: id
},
success: function (data) {
document.getElementById("cmnt"+id).innerHTML=data;
},
error: function (err, req) {
alert(err)
},
async: false
});
});
setTimeout("show_comments()", 5000);
}
The PHP
model
public function showcmnts(){
$sql="select * from tbl_cmnt
where postid='".$this->input->post("id")."'";
$query = $this->db->query($sql); return $query->result();
}
controller
public function show_comments(){
$data['cmntlist'] = $this->Group_model->showcmnts();
$this->load->view('group/grp_cmnts', $data);
}
view
foreach ($cmntlist as $cmnt):
echo $cmnt->comment . "<br>";
endforeach;
even though I set async: false in the ajax success function I can only get the last id(id of the last div) inside the ajax success function.but when i alert the id(id of the div) above the ajax part i am getting the correct id . so how can I pause the loop until ajax function finishes.sorry for my bad English please help me
Try to wrap your ajax call to immediately invoked function and pass id to it:
$('div#P_all_posts>div').each(function () {
id = this.id.replace("post", "");
(function(id) {
$.ajax({
url: 'http://localhost/seppro/index.php/group/show_comments',
type: 'post',
data: {
id: id
},
success: function (data) {
document.getElementById("cmnt" + id).innerHTML = data;
},
error: function (err, req) {
alert(err)
},
async: false
});
})(id)
});
It seems like your id var is global, and on each loop it rewrites its value, and by the time ajax is completed, id is equal to last value in loop.
The error seems to be in the fact that you never call the function show_comments() for first time in the the script
I recommend you to use this when you call it
setInterval(show_comments(), 5000)
And remove the setTimeOut() from show_comments()
Or you can just keep setTimeOut() and call show_comments() inside the script path or in the function you are going to call it

Postponing window.location to allow time for AJAX

I have an index page which I'd like to use to set up a local database before moving on to another page. However, whenever I have the window.location code activated none of the other functions run, but when I comment it out the other functions run fine. Any ideas to what would be causing this and how I can get both the functions and the window.locations to work? Code is as follows:
<script>
var db = window.openDatabase("DB1", "", "DB", 1024 * 1000)
CreateDB(); //Creates local database tables
loadRouteList(); //Queries web server database using AJAX and inserts Routes
window.location = 'Application.html';
</script>
Functions Used:
function CreateDB() {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Routes(id INTEGER PRIMARY KEY, routeID TEXT, customerID TEXT, stopSeq TEXT, driverID TEXT)', []);
});
};
function loadRouteList() {
var dataObject = {
postDesignator: 'routes',
};
$.ajax({
url: 'http://url.php',
data: dataObject,
dataType: 'json',
type: 'post',
success: function (Result) {
for (var i = 0, len = Result.records.length; i < len; ++i) {
var route = Result.records[i].record;
insertRoute(route.routeID, null, null, null);
}
}
});
}
use callbacks! I modified your code:
<script>
var db = window.openDatabase("DB1", "", "DB", 1024 * 1000);
CreateDB(); //Creates local database tables
loadRouteList(function() { window.location = 'Application.html'} );
</script>
Functions Used:
function CreateDB() {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Routes(id INTEGER PRIMARY KEY, routeID TEXT, customerID TEXT, stopSeq TEXT, driverID TEXT)', []);
});
};
function loadRouteList(callback) {
var dataObject = {
postDesignator: 'routes',
};
$.ajax({
url: 'http://url.php',
data: dataObject,
dataType: 'json',
type: 'post',
success: function (Result) {
for (var i = 0, len = Result.records.length; i < len; ++i) {
var route = Result.records[i].record;
insertRoute(route.routeID, null, null, null);
}
// this is the so called callback, that gets executed AFTER the ajax has finished
if(callback) { callback(); }
}
});
}
By definition, AJAX is Asynchronous, so if you run those functions and you don't wait them to be completed, your code will go on without waiting them. So you arrive at the point that your location changes due to your line. You have to wait until all your requests are done before going on, and to do this you have to change the code inside your functions. If you post them we could help you.
EDIT
In my opinion, the best way to do it is to pass a callback to your function:
function CreateDB() {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Routes(id INTEGER PRIMARY KEY, routeID TEXT, customerID TEXT, stopSeq TEXT, driverID TEXT)', []);
});
//if even this piece of code is async you should read docs and check how to call a function after the query executed
};
function loadRouteList(callback) {
var dataObject = {
postDesignator: 'routes',
};
$.ajax({
url: 'http://url.php',
data: dataObject,
dataType: 'json',
type: 'post',
success: function (Result) {
for (var i = 0, len = Result.records.length; i < len; ++i) {
var route = Result.records[i].record;
insertRoute(route.routeID, null, null, null);
}
if(callback) {
callback();
}
}
});
}
And then use it this way:
var db = window.openDatabase("DB1", "", "DB", 1024 * 1000)
CreateDB(); //Creates local database tables
loadRouteList(function() {
window.location = 'Application.html';
});

AJAX not firing before Callback

I'm attempting to run an AJAX query and insert the results into a local database before moving onto a new window.location. However, the success function to insert the results does not run. Instead the callback function causes the new page to load. If I comment out the if (callback {callback();} then the AJAX completes the inserts, but the window.location code is obviously not called. The callback function seems to get called before the AJAX success function is completed. How do I get the AJAX success to insert the results before moving on? Here's the code I'm using:
<script>
var db = window.openDatabase("MantisMobileDB1", "", "MantisMobileDB", 1024 * 1000);
function CreateDB() {
db.transaction(function (tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS Routes(id INTEGER PRIMARY KEY, routeID TEXT, customerID TEXT, stopSeq TEXT, driverID TEXT)', []);
});
}
function insertRoute(routeID, customerID, stopSeq, driverID) {
db.transaction(function (tx) {
tx.executeSql('INSERT INTO Routes (routeID, customerID, stopSeq, driverID) VALUES (?, ?, ?, ?)', [routeID, customerID, stopSeq, driverID], CountReturns);
});
}
function loadInitialRouteList(callback) {
var dataObject = {
postDesignator: 'routes'
};
$.ajax({
url: 'http://url.php',
data: dataObject,
dataType: 'json',
type: 'post',
success: function (Result) {
for (var i = 0, len = Result.records.length; i < len; ++i) {
var route = Result.records[i].record;
insertRoute(route.routeID, null, null, null);
}
if (callback) { callback(); }
}
});
}
if (localStorage.getItem('exitsatus') === null) {
CreateDB();
loadInitialRouteList(function () { window.location = 'Application.html'; });
}
else {
window.location = localStorage.getItem('exitsatus');
}
</script>

How do I load initial data via javascript? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 years ago.
I want to preload 9000 records via either a file or a whatever is best. The idea is I want to have there 9000 records somewhere and I want to load them into a sqlite DB via phonegap. I have all this working other then loading the data from somewhere. Here is what i have so far
I have a file records.csv file and here is my code
function populate_events_from_csv(db){
var event_data;
$.ajax({
type: "GET",
url: "records.csv",
dataType: "text/csv",
error: function (request, status, error) {
console.log('fail');
console.log(request.responseText);
},
success: function(data) {
console.log('success');
event_data = $.csv.toObjects(data); }
});
console.log(event_data);
db.transaction(function(tx) {
var q = 'INSERT INTO Events (id, name) VALUES (?, ?)';
_(event_data).each(function(row) {
tx.executeSql(q, [row.id, row.name]);
});
});
}
This approach would work but it fails because of the double and single quotes in the records csv
If anyone sees what i am doing wrong or another solution to initially inserting these 9000 records
function populate_events_from_csv(db) {
var event_data;
$.ajax({
type: "GET",
url: "records.csv",
dataType: "text/csv",
error: function (request, status, error) {
console.log('fail');
console.log(request.responseText);
},
success: function (data) {
console.log('success');
event_data = $.csv.toObjects(data);
db.transaction(function (tx) {
var q = 'INSERT INTO Events (id, name) VALUES (?, ?)';
_(event_data).each(function (row) {
tx.executeSql(q, [row.id, row.name]);
});
});
}
});
}
Why not convert the data into JSON, which will make it load faster into your javascript (minimal parsing), and simplify your code at the same time?
Once JSONized, you will be able to write
function populate_events(db, url) {
$.getJSON(url).done(function(data) {
db.transaction(function (tx) {
var q = 'INSERT INTO Events (id, name) VALUES (?, ?)';
$(data).each(function (index, row) {
tx.executeSql(q, [row.id, row.name]);
});
});
}).fail(function(request, status, error) {
console.log('fail');
console.log(request.responseText);
});
}
Converting CSV to JSON is left as an exercise, but there are many tools out there that can handle the task. I would use a Python script (csv + json libraries).

Categories

Resources