PDA

View Full Version : How do I check for errors when using EditorGridPanel with a REST service?



kylemhall
20 Apr 2011, 5:02 AM
Hello All,
I'm working on an application that is using an Editor Grid to load and edit data from a REST service I have written. The problem is, when I edit a field, it never gets marked as clean, even though the REST service sends back a JSON encoded entity like this {"success":1} ( in a 200 response ). I also would like it to show a popup for errors when it receives an error. I would prefer it to be a 400 response with {"message":"This is an error message"}, but I could go with a 200 with an entity {"success":0,"message":"This is an error message"} if I need to.

I'm having a lot of trouble find the correct areas in my code to place listeners. Any help would be greatly appreciated.

My code:


Ext.namespace('BizWerks.grid');

BizWerks.grid.DocumentsGrid = Ext.extend(Ext.grid.EditorGridPanel, { title: 'Documents', border: true,

initComponent: function() {
var proxy = new Ext.data.HttpProxy({
url: '/api/rest/documents',
headers: {
'Accept' : 'application/json'
},

listeners: {
write: function(){
alert( "grid.proxy.write" );
},
exception: function(proxy, type, action, options, response, arg) {
// Exception fires on every PUT, but *not* on any GETs, why?
if (type === 'remote') { // success is false
if ( ! response.success ) { // Added to see if this is really a failure.
console.log( response );
}
}
},
},

});

var reader = new Ext.data.JsonReader(
{
idProperty: 'id',
totalProperty: 'totalCount',
successProperty: 'success',
messageProperty: 'message',
root: 'items',
fields: [
{name: 'id', mapping: 'id'},
{name: 'name', mapping: 'name'}
],
}
);

// SimpleWriter just sends standard variables to the server,
// rather than encoding them in JSON or XML.
var writer = new BizWerks.data.SimpleWriter();

var store = new Ext.data.Store({
restful: true,
remoteSort: true,
proxy: proxy,
reader: reader,
writer: writer,
});

var colModel = new Ext.grid.ColumnModel({
defaultSortable: true,
columns: [
{
header: 'ID',
dataIndex: 'id',
},
{
header: 'Name',
dataIndex: 'name',
editor: new Ext.form.TextField({ allowBlank: false }),
}
]
});

var bbar = new Ext.PagingToolbar({
//pageSize: 10,
store: store
})

Ext.apply(this, {
loadMask: true,
autoHeight: true,
store: store,
colModel: colModel,
bbar: bbar,

listeners: {
exception: function(proxy, type, action, options, response, arg) {
//This exception *never* gets thrown, even if the reponse from
// the server is a 400 with a message, or a 200 with success=0
this.rejectChanges();
Ext.Msg.alert('Error', response.raw.message)
},
afteredit: function(e){
// How do we check for success here?
e.record.commit();
},
},
});

BizWerks.grid.DocumentsGrid.superclass.initComponent.apply(this, arguments);
},

onRender: function() {
this.store.load();
BizWerks.grid.DocumentsGrid.superclass.onRender.apply(this, arguments);
}
});

Ext.reg('documentsgridpanel', BizWerks.grid.DocumentsGrid);


Thanks again,
Kyle

Screamy
20 Apr 2011, 5:19 AM
I use a global Ajax error/success handler, where all Ajax based requests pass through the handler. In the Ext.onReady() block during my initial application load, I do something like this:



Ext.ns('myApp.global');
Ext.Ajax.on("requestcomplete", myApp.global.ajaxRequestHandler, this);
Ext.Ajax.on("requestexception", myApp.global.ajaxRequestHandler, this);
Where the request handler looks like this:



myApp.global.ajaxRequestHandler = function(connection, response, options)
{
// server blowup returns no status in response..
if (response.status == undefined) {
window.location = "error.action?status=Error&statusText=An error occurred while processing your request. Please contact Tech Support.";
}
// session timeout handler redirects to a session timeout page, where the first
// line is a comment indicating a timeout.
else if (response.status == 200) {
if ( response.responseText.match(/^<!--SESSION TIMEOUT-->/) != null)
{
// perform the equivalent of a full-page submit, so that the output isn't directed
// to the target Ext component.
window.location = "sessionTimeout.action";
}

// if needed, examine the response and look for any other 'logical' error
// conditions here, then redirect as appropriate.

}
else if (response.status == 403)
{
window.location = "accessDenied.action";
}
else if(response.status == 404) {
window.location = "404.action";
}
else {
window.location = "error.action?status=Error Code: " + response.status + "&statusText=Please contact tech support. Error Message: " + response.statusText;
}
};

kylemhall
20 Apr 2011, 6:11 AM
While I appreciate the reply, this doesn't really help me with my problem.

I also tried your code, but get this error:
l.fireFn is undefined
http://192.168.1.36:3000/static/extjs/ext-all-debug.js
Line 310

Screamy
20 Apr 2011, 6:16 AM
Sorry about that, I somehow skipped completely over the part about marking items as clean...

I think the problem is that you're not return 'success: true' in your JSON response (as opposed to the 'success: 1' you're currently returning).

kylemhall
25 Apr 2011, 3:27 AM
You were indeed correct about this, I modified my server to return success as a boolean, and now my proxy no longer fires an exception every time, but I still don't know how to connect a successful PUT event to the committing of the edited record, or conversely, how to reject the edited record and display an error if the server sends back 'success: false' with a message.


Sorry about that, I somehow skipped completely over the part about marking items as clean...

I think the problem is that you're not return 'success: true' in your JSON response (as opposed to the 'success: 1' you're currently returning).

varunach
25 Apr 2011, 1:39 PM
use this on the grid :


viewConfig : {
markDirty : false
}