PDA

View Full Version : [SOLVED] Jayrock JSON / Grid woes



benny_boi
26 Sep 2007, 10:48 PM
Hi All,

I'm hoping someone may have come across the cause of this - I've no doubt I've done something fundamentally wrong in trying to apply the tutorial and tid-bits I've found in the forum on talking to Jayrock JSON-RPC web services with Ext.

Background - I'm using ASP.Net (v2.0) with JayRock (v0.9.8316) and Ext framework (v1.1.1). I've created a "Test" web service handler (ASHX) that has one method - "getEmployeeList" - this currently returns sample employee data from MS's AdventureWorks 2005 database and is wired up with JayRock. I've tested that it returns valid data, and that it's ?proxy implementation seems sound.

Based on the Jayrock Tutorial (thanks FritFrut), and the Jayrock channel suggestions from mdissel (http://extjs.com/forum/showthread.php?t=8501), I've tried to wire this test service up to an Ext grid. The grid loads, and populates a number of rows - but all blank. The number of grid rows Ext creates is directly related to the size of the JSON result-set that is sent to the browser.

I've snooped using Firebug, and the JSON returned is shown below (I've limited the result set to 4 rows for the purposes of posting here).



{"id":1,"result":{"Table":{"columns":["EmployeeID","FirstName","LastName","JobTitle"],"rows":[[278,"Garrett","Vargas","Sales Representative"],[281,"Shu","Ito","Sales Representative"],[217,"Michael","Raheem","Research and Development Manager"],[285,"Jae","Pak","Sales Representative"]]}}}

The HTML code is shown below. I've noticed that JayRock returns the content type of "text/plain; charset=utf-8", not "application/json", so I've taken out mdissel's interceptor function on the "Ext.data.Connection.handleResponse" method (it doesn't get used, and appears to have made no difference to the problem).



<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<link rel="stylesheet" type="text/css" href="/CSS/ext-all.css" />

<script type="text/javascript" language="javascript" src="/JS/ext-base.js"></script>
<script type="text/javascript" language="javascript" src="/JS/ext-all.js"></script>
<script type="text/javascript" language="javascript" src="/Test.ashx?proxy&v=2"></script>
<script type="text/javascript">
var ext_channel = function(call)
{
if (typeof(call.callback) !== 'function')
throw new Error("The EXT channel does not support synchronous methods.");
call.yuiconn = Ext.Ajax.request (
{
url: call.url ,
params: {"JSON-RPC": Ext.encode(call.request)} ,
success: function(response, options) {
call.callback(response);
},
failure: function(response, options) {
call.callback({xhr: response});

}
}
);
return call ;
};

getEmployeeList_proxy = function()
{
getEmployeeList_proxy.superclass.constructor.call(this);

this.load = function(params, reader, callback, scope, arg) {
Test.rpc["getEmployeeList"](
this.loadResponse.createDelegate(this, [reader, callback, scope, arg], true )
).call(ext_channel);
}

this.loadResponse = function(response, reader, callback, scope, arg) {
var result;
result = reader.read(response) ;
callback.call(scope||this, result, arg, true) ;
}
} ;
Ext.extend(getEmployeeList_proxy, Ext.data.DataProxy, {}) ;

Ext.onReady(function(){
var px = new getEmployeeList_proxy();

var rdef = Ext.data.Record.create([
{name: 'EmployeeID'},
{name: 'FirstName'},
{name: 'LastName'},
{name: 'JobTitle'},
]);
var rdr = new Ext.data.JsonReader({root: 'result.Table.rows'}, rdef ) ;
var ds = new Ext.data.Store({proxy: px, reader: rdr, remoteSort: false}) ;
var cm = new Ext.grid.ColumnModel([
{header: "Employee Number", width: 100, dataIndex: 'EmployeeID'},
{header: "First Name", width: 150, dataIndex: 'FirstName'},
{header: "Last Name", width: 150, dataIndex: 'LastName'},
{header: "Position", width: 250, dataIndex: 'JobTitle'}
]);
cm.defaultSortable = true;

// create the grid
var grid = new Ext.grid.Grid('staff-grid', {
ds: ds,
cm: cm
});
grid.render();

ds.load();

});
</script>
</head>
<body>
<div id="staff-grid" class="x-grid" style="border: 1px solid #c3daf9; overflow: hidden; width:670px; height: 400px;"></div>
</body>
</html>


I've no doubt I've made some fundamental error in the proxy or Jayrock channel code which is tripping up the grid. The grid seems to be accessing the JSON return object to some degree of success though - as I mentioned - it creates a number of blank grid rows directly related to the number of "rows" returned in the dataset. And if I set the "root" config option of the JsonReader to anything besides {root: 'result.Table.rows'}, I get an actual JS error in Firebug.

Anyone who can point out where my stupidity lies would be my hero - I've been going round in circles for a few days with this.

Many thanks,

Ben

benny_boi
26 Sep 2007, 11:42 PM
PS: Noting the "call.yuiconn" definition on the JayRock channel, I tried using the YUI base and adapter rather than using ext-base.js - both behaved identically..

<scratches head> I'm sure it's something obvious... :-(


Hi All,

I'm hoping someone may have come across the cause of this - I've no doubt I've done something fundamentally wrong in trying to apply the tutorial and tid-bits I've found in the forum on talking to Jayrock JSON-RPC web services with Ext.

benny_boi
4 Oct 2007, 2:10 AM
Special thanks to FritFrut, who worked out what was going on with my empty grid rows...

Because of the default way JayRock 0.9 passes row definitions separately to the column data in it's JSON-RPC results, mapping to the fields by name was returning blank grid rows.

The correct way to define the record with the JSON result shown above was to use the index number of the field in the result set instead of the name - as below:



Ext.data.Record.create([
{name: 'EmployeeID', mapping: 0},
{name: 'FirstName', mapping; 1},

etc


Hope this helps someone else if they're playing with JayRock and Ext...

zlarson
9 Oct 2007, 11:46 AM
i have tried following your above example but get this message:

Microsoft JScript runtime error: The EXT channel does not support synchronous methods.



My question is: in this code:
if (typeof(call.callback) !== 'function')
throw new Error("The EXT channel does not support synchronous methods.");

where is call.callback set?

thanks.

benny_boi
23 Oct 2007, 1:24 AM
Hi zlarson,

Sorry for the delay in replying - I've been on hols and only just caught up on email.

In answer to your question, the pointer to the callback function gets passed to the data proxy - in this case "getEmployeeList_proxy" (which extends Ext.data.DataProxy load method) recieves this, and passes in onto the "ext_channel" function, which creates an Ajax call, and handles the asynchronous response.

If you're using the above code unmodified, the proxy is called by an Ext.data.Store, and hence the callback comes from Ext (NOTE: My code was based on v1.1.1 of the Ext library - I havent tested it on v2.0 b1).

Since posting this topic, I've written a clean little patch for the JayRock v0.9 code that extends the dynamic Javascript generation to emit Ext compatible dataproxy code etc - I'll post this patch on here shortly.

If you're still having drama's getting the above code to work, send me a private message with your email address, and I'll send you a ZIP of the sample web app I threw together.

Cheers,

Ben