phonegap sqllite Database: the statement callback raised exception - ajax

i am having this strange "the statement callback raised an exception or error did not return false"
it is just a simple databases example.
my code is on github here:
https://github.com/prantikv/phonegapDBdemo
please read the comments in the code it explains everything.
i suspect the problem is in the ajax callbacks for the database.
if that is true than how can i make the ajax callback wait for data in sql-lite/phonegap?
function formSent(){//fired when form is submited
alert("formSent called");
db.transaction(queryDB, errorTrans);
return false;
}
function errorTrans(err){ //error for formsent
alert("formsent "+err.message+"|"+err.code);//error is generated here
}
function createSuccess(){//just alerts on success
alert("DB Created");
}
function populateDB(tx) {//transaction obj is passed. Table Created not populated
alert("populateDB called");
tx.executeSql('CREATE TABLE IF NOT EXISTS myDB (id , data)');
}
function onDeviceReady(){
db= window.openDatabase("Database", "1.0", "Display Name", 4*1024*1024);
db.transaction(populateDB, createERR, createSuccess);
}
function createERR(err){//error for create
alert("Create "+err.message);
}
AM i supposed to add return false for every database callback.if yes then which Boolean is to be returned when?
The phonegap doc examples dont have it http://docs.phonegap.com/en/2.2.0/cordova_storage_storage.md.html#Database

The error message usually isn't because of SQL, it is rather about exception that happens when you are executing callback for it. So you most probably have JS error happening.
I found
tx.executeSql('INSERT INTO myDB VALUES (?,?)', [username,email], insertSuccess, errorInsert);
on line 47 of index.js. It is lacking the (id,data) before VALUES. This causes the next SQL call
tx.executeSql('SELECT * FROM myDB', [], querySuccess, errorSelect);
to fail. Fix that and then try again.

Related

LockForUpdate causes Deadlock if table is empty

Currently I am trying to upload some images parallel with dropzone.js.
This is part of the code, that handles the upload.
\DB::beginTransaction();
$maxPos = GalleryImage::lockForUpdate()->max('pos');
try {
// some other code
// ....
$galleryImage->pos = $maxPos + 1;
$galleryImage->save();
} catch (\Exception $e) {
\DB::rollBack();
\Log::error($e->getMessage());
return response('An error occured', 500);
}
\DB::commit();
If I do not use the lockForUpdate() I end up with duplicate positions in database.
The problem with above solution ist, that if the table is empty I get the error:
Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction
But only for the second image I am uploading.
Additionally the autoincrement id skips the value 2 and goes like 1,3,4,5,6,7, ...
The Positions in the table are shown correctly 1,2,3,4....
I think the problem has to do with the table beeing empty initially, as I did not notice this problem, when there are already some entries in the table.
Any suggestions what I am doing wrong? Or Maybe using lockForUpdate() in combination with an aggregate function is wrong at all...
I recommend a different approach to transactions.
try {
app('db')->transaction(function ()) {
$maxPos = GalleryImage::lockForUpdate()->max('pos');
// other code (...)
$galleryImage->pos = $maxPos + 1;
$galleryImage->save();
}
} catch (\Exception $e) {
// display an error to user
}
Should any exception occurs inside the callback, the transaction will rollback and free any locks.

parse background job each() does not go through all records?

I wrote a cloud job to insert a lowercase version of a user's first name and last name in the user object so that I can perform a search from my client app.
When I did run this job on a dev parse app that had like 40 users it worked great.
When I did run this on my production app however it did not update all of my records. I have a few thousands users at the moment and I was expecting this cloud job to take care of all of them as explained here:
http://blog.parse.com/2013/05/13/launch-and-iterate-parse-data-migrations/
" The new each method on Parse.Query objects allows you to do just that. Even if you have tens of thousands of objects or more in a collection, it will return each one of them, giving you an opportunity to modify them as you see fit."
So then my question is why does this function leave behind over half of my database? It only worked on a bunch of users, maybe a few hundred.
How can I make this function affect my WHOLE DATASET in the User table?
Parse.Cloud.job("migration1", function(request, status) {
// Set up to modify user data
Parse.Cloud.useMasterKey();
// Query for all users
var query = new Parse.Query(Parse.User);
query.each(function(user) {
// Set and save the change
var firstname = user.get("firstname");
if(firstname) {
user.set("searchfirstname", firstname.toLowerCase());
} else {
user.set("searchfirstname", "");
}
var lastname = user.get("lastname");
if(lastname) {
user.set("searchlastname", lastname.toLowerCase());
} else {
user.set("searchlastname", "");
}
return user.save();
}).then(function() {
// Set the job's success status
status.success("search migration completed successfully.");
}, function(error) {
// Set the job's error status
status.error("Uh oh, something went wrong with search migration");
});
});
EDIT:
Ok so when I look at the error logs I see this:
E2014-10-18T15:48:49.984Z] v63: Ran job searchMigration with:
Input: {}
Failed with: TypeError: Cannot call method 'toLowerCase' of undefined
I tried to check for undefined in any way I could think of and I still get the same problem.
What I tried to check for undefined is this:
if(lastname === undefined || lastname === void 0 || typeof lastname == 'undefined') ...
I still get the toLowerCase of undefined error and I think that is why the job does not affect all of my user table since it stops...
Any suggestions?
So, I finally figured out why the job did not go through all the records but it would stop after a few records "randomly"...
I had an AfterSave hook for the user which was triggered at each iteration of the above job...
In that after save it would generate an error at times and make the Job fail.
So, for some reason I thought the after save hook would have not been triggered by a save done on the user while inside of a Job.
That's it. Now it all works.

Backbone.js Backbone.wrapError function

This questions was about Backbone 0.9.2
Since upgrading to Backbone 0.9.10 we've chosen to override Backbone.sync instead and it works like a charm.
December 2012 - (v0.9.9) Backbone.wrapError has been removed.
February 2013 - It looks like WrapError will be brought back in the next version of Backbone, but overriding backbone.sync is the way to go.
(sorry for the long read)
I'm modifying the Backbone.wrapError function and I'm baffling by a line. I know what the line does, but not WHY it is necessary.
resp = model === originalModel ? resp : model;
resp ends up being the textStatus/errorType ie: "error" "timeout"
"parse error"
model is the XHR request object
originalModel is a reference to the Backbone.Model instance which ultimately called this function
I have a good grasp on what Backbone.wrapError does, what it returns and how it is used but I can't seem to understand the purpose of the above line.
Backbone's documentation states that wrapError will 'Wrap an optional error callback with a fallback error event,' which is true. Additionally, I've learned is that Backbone.wrapError is called 4 times in the library from within the fetch, save, destroy and reset functions in order to ensure that AJAX errors do not go unnoticed by the library. For example, if an AJAX error callback is passed into the fetch method it will be executed with a few parameters passed along, if not, the model will trigger an error event with the same few parameters passed along.
Sample call:
options.error = Backbone.wrapError(options.error, model, options);
Backbone.wrapError:
Backbone.wrapError = function(onError, originalModel, options) {
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
onError(originalModel, resp, options);
} else {
originalModel.trigger('error', originalModel, resp, options);
}
};
};
The problem that arises with this line (resp = model === originalModel ? resp : model;) is that model and resp correspond to the first 2 parameters within the jQuery/Zepto error callback parameter list. The first problem I have is with the naming of these parameters (model, response), because while debugging I've seen that those 2 parameters are jqXHR/xhr and textStatus/errorType. The textStatus/errorType parameters usually end up being "error" but (according to the docs) can also be "timeout" "parse error" etc. The comparison of model === originalModel makes no sense to me. A hard comparison on an XHR object and a Backbone.Model instance will always fail, and model will be stored into response (resp), which is fine because the model is actually the XHR response object... this line just seems pointless to me, but I went ahead and included it in my modified wrapError method.
Because model === originalModel always evaluates to false, the line seems to be an elaborate version of resp = model; which is useless, because you could just remove the line entirely and the model parameter could be passed into originalModel.trigger('error', originalModel, resp, options); instead of resp.
Is there any instance where model === originalModel could possibly evaluate to true?
Anybody with more experience in Backbone.js, AJAX have an answer/explanation of why this line is necessary?
TLDR/CLIFFS:
The weird little line below is used to determine weather the error callback was triggered from a failed validation at the model level, or from a failed AJAX call from the fetch, save, or destroy methods (which all call Backbone.sync). If the failure is from validation, it does not change the resp variable because resp should already hold useful information returned by validate (such as an errors array or a string about the error). If the failure is from a bad AJAX request, the XHR object is stored into resp because the XHR is the most informative item available. Unfortunately, the XHR is passed into this function as model and Backbone documentation fails to point out that this parameter does not always represent a model. Resp is meant to hold useful response information about the error(s), and is sent to the error callback or a thrown error event.
Okay. I learned some things about this weird line.
resp = model === originalModel ? resp : model;
In Backbone there are AJAX errors and Validation errors. Conveniently, Backbone funnels both errors into the same function -- the AJAX error callback. The problem is that the arguments passed into these functions are inconsistent. When there is an AJAX error an XHR object is available, but not during a validation error.
If there is no callback present, Backbone will throw and 'error' event with the same parameters that would have been passed into the error callback. (line 7 and 9 below).
After a successful AJAX request, your JSON data can be optionally passed through the model's validate function. In Backbone, the validate function should return false or nothing at all when there are no errors. When there ARE errors, it is typical to return an array such as ['invalid username', 'password too long', 'etc...'] Anything returned from validate (usually an error messages array) is passed into the 'wrapped' error callback as the resp parameter and the model itself is passed as model!
The _validate function is a bit sloppy and has multiple return statements, but when validation fails, line 9 is hit. Line 9 of the _validate function passes this (the model), error (returned from the models validate method), options (ajax options, success, error, timeout etc). This differs from an AJAX error which will pass in xhr (xmlhttprequest object), errorType ('error' 'timeout' 'parse error' etc), options (ajax options).
validate error: error(model, validate_return_value, options)
ajax error: error(xhr, errorType, options)
1 _validate: function(attrs, options) {
2 if (options.silent || !this.validate) return true;
3 attrs = _.extend({}, this.attributes, attrs);
4 var error = this.validate(attrs, options);
5 if (!error) return true;
6 if (options && options.error) {
7* options.error(this, error, options);
8 } else {
9 this.trigger('error', this, error, options);
10 }
11 return false;
12 }
The strange line of code above is necessary because, this one function handles errors from 2 different methods. AJAX and Validation. Those 2 send it different parameters, so this is meant to normalize them and throw events with consistent parameter lists.
When a validation error occurs, the model does not change so the model that is passed into the error callback is exactly equal to the originalModel. The purpose of the resp parameter is to hold information about the error itself. When there's an AJAX error, 'timeout' 'parse error' or 'error' are simply not as informative as the XHR object.
That weird little line determines weather the error callback was accessed from _validate or through a normal AJAX error such as a 404. When it is accessed from validate, resp is the value returned from validate. It should be informative, and useful data for the front-end templates to display. When the resulting error is from a HTTP error, the most useful information about that error is the XHR object which is passed into this function as the MODEL parameter.
A hopefully simplified approach to the wrapError and validate functions
Backbone.wrapError = function(ajax_error_callback, model_or_xhr, ajax_options) {
return function(model_or_xhr, error_info) {
if there was an ajax error, error_info = the xhr object
if there was a validation error, error_info = whatever was returned from validate
if there's an error callback {
run the error callback with (the original model, error_info, ajax_options) as parameters
if there is not an error callback
throw an event called 'error' with (the original model, error_info, ajax_options) as parameters
}
};
};
original:
Backbone.wrapError = function(onError, originalModel, options) {
return function(model, resp) {
resp = model === originalModel ? resp : model;
if (onError) {
* onError(originalModel, resp, options);
} else {
originalModel.trigger('error', originalModel, resp, options);
}
};
};
The * shows that error callback called from here

Extjs store.on('save', afterSave(resp));

I have a simple ExtJs (3.4) Grid with a Writer. When the user makes some changes the store is saved to the server as follows:
store.on('save', afterSave(resp));
All is fine. However, I want to get a response as to wheather the record has been saved successfully, failed or an update conflict happed. How to best do this?
Are you using Ext.data.proxy.Ajax to load your stores? If so, you can use the reader property to evaluate and handle the server responses.
Another option would be to make AJAX called directly and handle the responses from there as well
I used exception listener to parse the data as suggested here. But, is this the right way to do this.
Ext.data.DataProxy.addListener('exception', function(proxy, type, action,
options, res) {
if (type == 'response') {
var success = Ext.util.JSON.decode(res.responseText).success;
if (success) {
console.log('UPDATE OK');
} else {
console.log('UPDATE FAILED');
}
}
});

How to Handle Exception Occured In Web method which Is Called In a Ajax Call

I'm calling a web method ajax call which returns a value say "Completed". In that web method whenever exception occurs, it is not returning any value and I am not able to throw the message about the exception to the user. What should I do?
If you could show us some could that would help :)
Maybe you could try, catch the expected Exception and return a string value other than "Completed" and could use this value to tell the user what when wrong.
Suppose that the Ajax call this method :
public string Test(){
string ab1 = "ab1";
try{
int.Parse(ab1);
}
catch
{
return "Error";
}
return "Completed";
}
Something like that, I wrote it on the fly, maybe there are mistakes, just tell me, it was just to present my idea. And in your javascript, upon receiving "Error" you could warn the user something went wrong.

Resources