PDA

View Full Version : XmlReader, Store, and getting nowhere fast...



DigitalSkyline
3 May 2007, 11:31 AM
Ok so this is my first attempt at using the Store and XmlReader... my code was working fine using prototype but I want to use Ext w/YUI so including another library would obviously suck;).

This is a port of the code, but I'm getting no results, I've spent several hours trying to find a solution ... now I'm hoping someone might help me sort this problem.

By the way, the arg var will actually be a url, and I'd also like to also know how I might post variables to the server in this context. In prototype, I'd use the very simple Ajax functions, here I'm at a loss as I'm afraid the examples aren't very thorough in this area.:((

I'm sure once this is solved I'll be on my way with grids ect.!

Help? plz!



arg = 'test.xml';
// create the Data Store
var ds = new Ext.data.Store({
// load using HTTP
proxy: new Ext.data.HttpProxy({url: arg, method:'post'}),
// the return will be XML, so lets set up a reader
reader: new Ext.data.XmlReader({
// record are enclosed in an "xml" tag
record: 'xml'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic (I ignored this, to no avail)
{sid: 'sid', mapping: 'sid'},
{sid: 'url', mapping: 'url'},
{sid: 'fid', mapping: 'fid'},
{sid: 'fp', mapping: 'fp'},
{sid: 'fnm', mapping: 'fnm'},
{sid: 'body', mapping: 'body'}
])
});
ds.on('beforeload', function(store, options) {
//Viewer.setStatus('Accessing...','updating');
alert('updating'); // not being triggered
});
ds.on('loadexception', function() {
//Viewer.setStatus('Done','done');
alert('An error occured while communicating with the server..'); // not being triggered
});
ds.on('load', function(store, record, options) {

alert('loaded'); // this is not being triggered.
// Process whatever you want here. The dataset will be loaded at this point
var tmp;
tmp = record.sid;
if(tmp) sid = tmp;
tmp = record.url;
if(tmp) url = tmp;
tmp = record.fid;
if(tmp) fid = tmp;
tmp = record.fp;
if(tmp) fp = tmp;
tmp = record.fnm;
if(tmp) fnm = tmp;
tmp = record.body;
if(tmp) cholder = tmp;

});



contents of test.xml


<xml>
<sid>273896425763</sid>
<url>/</url>
<fid>1177123523287</fid>
<fnm>about.xml</fnm>
<fp>\content\</fp>
<body>
<![CDATA[
<center>
<p>

</p>
<p>
</p>
</center>
</body>
]]>
</xml>

tab
3 May 2007, 1:11 PM
Is your code wrapped in something like this?


Ext.onReady(function(){


Are you running firebug to try to find the point of failure?

And there is an xml example somewhere. It is often easiest to get the example running then morph it into your program.

If you are doing these things you might want to post some about what is happening in firebug.

Zakaroonikov
3 May 2007, 2:31 PM
Did you call the ds.load() function?

DigitalSkyline
3 May 2007, 2:47 PM
Tab,
No its located in a function outside of the on ready event. Its called from other functions, but its still on the same page and has access to the Ext libs... there are no errors being reported.

Zakaroonikov ,
No but thank you, that at least got me to the point of triggering the loadexception event... (it's progress!)

DigitalSkyline
3 May 2007, 3:07 PM
Ok I fixed some things, changed to point to the real app instead of the xml file and I get a successfull load but I'm only returning undefined in my variables... I must not be accessing the data store correctly ... any tips?

jsakalos
3 May 2007, 3:10 PM
What about tracing execution of the code with firebug to see where undefined comes from?

tryanDLS
3 May 2007, 3:12 PM
Your reader mapping is wrong - look at the xml examples - the properties are name and mapping, not sid.

Animal
4 May 2007, 12:24 AM
Your Record definition is wrong.

The documentation is present in Ext.data.Record for the create() method, but with a syntax error that means it won't generate.

Hopefully, the addition of "@method create" to the comments for it will bring it out in the next release. Jack, will that work?

If you look at the source, and the comments for Ext.data.record.create, you'll find a full explanation of the format for a Record definition.

Basically:

* @param {Array} o An Array of field definition objects which specify field names, and data types, and a mapping for an Ext.data.Reader to extract the field's value from a data object.

Each field definition object may contain the following properties:
name {String} The name by which the field is referenced within the Record. This is referenced by, for example the dataIndex property in column definition objects passed to Ext.grid.ColumnModel

mapping {String} (Optional) A path specification for use by the Ext.data.Reader implementation that is creating the Record to access the data value from the data object.

If an Ext.data.JsonReader is being used, then this is a string containing the javascript expression to reference the data relative to the record item's root.

If an Ext.data.XmlReader is being used, this is an Ext.DomQuery path to the data item relative to the record element.

If the mapping expression is the same as the field name, this may be omitted.

DigitalSkyline
4 May 2007, 1:22 PM
Your reader mapping is wrong - look at the xml examples - the properties are name and mapping, not sid.

Ah yeah I should've mentioned I already fixed that (where I said I fixed some things)

DigitalSkyline
4 May 2007, 1:41 PM
Ok just to clarify, the record portion of the code above should look like -



reader: new Ext.data.XmlReader({
// record are enclosed in an "xml" tag
record: 'xml'
}, [
// set up the fields mapping into the xml doc
// The first needs mapping, the others are very basic
{name: 'sid', mapping: 'sid'},
{name: 'url', mapping: 'url'},
{name: 'fid', mapping: 'fid'},
{name: 'fp', mapping: 'fp'},
{name: 'fnm', mapping: 'fnm'},
{name: 'body', mapping: 'body'}
])



I'm still getting undefined for the variables:



//snip
ds.on('load', function(store, record, options) {
if(record.sid) sid = record.sid;
if(record.url) url = record.url;
if(record.fid) fid = record.fid;
if(record.fp) fp = record.fp;
if(record.fnm) fnm = record.fnm;
if(record.body) cholder = record.body;
// snip...

jsakalos
4 May 2007, 1:50 PM
I don't think that you have your data directly under record. Like record.sid. If I remember well there is data under record.

Try record.data.sid, or firebug will tell you exactly.

jsakalos
4 May 2007, 2:00 PM
One more thing. You posted load event hadler and this event is fired after all records are read. Argument that you call record is records in fact and it's array.

I'm advicing you cca 3rd time to use firebug to look what are real arguments you get in your handler.

DigitalSkyline
4 May 2007, 5:13 PM
I've tried just about every combination I can think of to get the data returned by "record". In the documentation it says Record has a get($) method but this returns an error when applied to records (object doesn't support this method). I also tried using the ArrayReader to no avail.

Dosen't anyone know how to return this data :/

As far as firebug, please excuse me for exposing my ignorance, but I've yet to install or use this app perhaps I'm making things harder on myself I'll try and give it a go as time permits. I spend much more time on server-side coding and while I'm by no means new to Javascript I'm pretty new to the latest OO methodologies.

Ext has re-ignited my interest in client-side scripting and I've just recently learned of its existance. I don't think it will be long before I'm churning out code and helping others but I'm still very new to this library.

jsakalos
4 May 2007, 6:04 PM
Hmmm, I cannot imagine how can you live as a javascript developer without firebug (or some other debugger). It's like driving a car without beeing able so see over (e.g. dirty) windshield. You can get somwhere but it's only by chance.

Firebug is free of charge as well as firefox and installation can be a matter of minutes.

DigitalSkyline
4 May 2007, 7:02 PM
Force of habit, having developed since before such tools existed.

lots of alerts and refreshes... lol.

So still no ideas on how to access this record data... and I've even installed firebug, stepped though the mountain of code, and still clueless. The sad thing is I could do this in prototype in about half the amount of code. I'm getting a little discouraged here so unless someone has actually done this and/or has an example of working code I'm heading out to get some beer.

Animal
4 May 2007, 9:28 PM
You are just wasting your own time and everyone's time by refusing to use a debugger.

This kind of thing is very simple to debug using Firebug. You can actually poke around inside your "Record" object to see what it really is.

Animal
4 May 2007, 9:31 PM
It's not



record.sid


Even in their current, broken state, the docs tell you that it's



record.get("sid")

Animal
4 May 2007, 9:32 PM
The fact that your "Record" doesn't appear to have a get method woud indicate that it's not a Record. GET FIREBUG.

DigitalSkyline
5 May 2007, 2:33 AM
Hey hombre if you read my post you would see that I already installed firebug, sorry if you think I'm "wasting your time". As far as the docs go they say its an array, I assumed an associative array/object but maybe thats not the case. I started with the example code for xml-grid.js but it connects to a grid and doesn't show how to access the variables directly.

Whatever is being returned to the load handler I really don't know - or what to look for in Firebug being that I've only had it for a few hours now.



load (http://extjs.com/deploy/ext/docs/output/Ext.data.Store.html#event-load) : (Store this, Ext.data.Record[] records, Object options)StoreFires after a new set of Records has been loaded.

jsakalos
5 May 2007, 2:42 AM
In firebug, go to the Source tab, put the breakpoint inside your event handler and run your code. When code stops on your breakpoint, look at the bottom right side and inspect the variables you see there.

This gives you reality as to what are the arguments of the handler.

jsakalos
5 May 2007, 2:44 AM
One note more: There is no such thing in javascript as associative array. Array is always number indexed array and object is something that may resemble an associative array.

Animal
5 May 2007, 2:47 AM
OK, so now you can use ext-all-debug.js, and step into your ds.load() call.

When you get in (it will take a while for Firebug to load the big script and navigate to the line) scroll carefully (It's a big file) to loadRecords, and set a break there.

Step INTO the proxy.load call and set a breakpoint in the proxy's loadResponse method.

Then you can click continue, and it should break in the proxy's loadResponse method, and you can look at the success flag, and the response object, and see if there's XML in it. You can check the response headers to see if Content-Type is "text/xml".

Then you can step into the reader.read() method and see how that goes to see if it can pull the data out of the response into put it into Records

That should get you started with proper debugging. It's what I went through when implementing paging grids. Getting down into code in a debugger - it's what developers do.

jsakalos
5 May 2007, 2:47 AM
And one more note: I really appreciate your persistence on getting the thing working. I always admire such people that don't give up on first failure.

Congratulations. Keep up. :)

DigitalSkyline
5 May 2007, 12:40 PM
No I'll work on it until it works... failure is not an option :)

Just to inform Firebug did help in watching the post/response ... it was returning a "411 length required" server error I assume because no actual post data was sent. Which leads me to my concurrent question on how to send post data via httpProxy(?)

In the interest of sanity I've set this to "get" for now which returns the proper xml response. (For whatever reason, in IE this was not a problem.)

But back to the issue at hand, "record" when moused over just shows record[] in firebug I'm not sure if this indicates an object or an array (maybe its an array of record objects). I haven't investigated yet -

I'm finding it hard to comprehend that no one has an idea/example of retrieving xml data for script manipulation via Ext... maybe I'll end up just going to the YUI libraries directly. But for now... Back to the grindstone.

jsakalos
5 May 2007, 12:50 PM
Firebug has many tabs. Most important (at this stage) are Script, Console and Net. I don't know what are installation defaults but with firebug you can explicitely see what was sent to servers by XHR and what the server sent back.

You see it in Console tab (maybe you need to check "Show XMLHttpRequests" in options. So you never need to wonder what and if was sent and what and if was received.

In the Script tab you can see the current line to be executed (on stopped script) and values of all variables (right hand side) known at that point. You can "open" variables that are arrays or objects.

And last, records[] is the array - probably an empty one - open it to see.

jsakalos
5 May 2007, 12:58 PM
Here is my code of working ds (I use json, not xml format). requestID and objName are my variables. Your baseParams will differ:



var ds = new Ext.data.Store({
baseParams: {
requestID: 'getData'
, objName: 'orgbList'
}
, proxy: new Ext.data.HttpProxy({method:'post', url:'/ajax.php'})
, reader: new Ext.data.JsonReader({
root: 'records'
, totalProperty: 'totalCount'
, id: 'orgbID'
}, [{name:'orgbID'}, {name:'orgbName'}, {name:'orgbDesc'}])
});

There are no listeners (event hadlers) attached to it but you can:



ds.on('load', function(store, records, options) {
debugger;
});
ds.load();

Animal
5 May 2007, 10:20 PM
You need to break in the Proxy's loadResponse method and step into the reader.read() call and examine how the XmlReader is extracting the data. It's a dead simple class, you should be able to understand exactly what's going on.