Greetings all,
No question, just sharing some experience.
I am not a great designer of interfaces. Never was. So I use javascript libraries to do that job for me. That works fine (the integration with NetKernel that is). I've tried Dojo (too slow), Prototype (not enough eyecandy) and am exploring ExtJS (looks promising, but so did the others :-) at the moment.
All these libraries have ways to handle requests which I of course handle the NetKernel way. Usually XML response is allowed, but JSON is quickly gaining ground and - pretty important in open source efforts - is often the first / best supported / best documented option.
No problem however, JSONFromXML does the job.
But maybe a bit too well.
Conside the typical database response :
<RESULTS> <ROW>
... first row data ...
</ROW> <ROW>
... second row data ...
</ROW> </RESULTS> |
Gets translated to
{"results": { "row": [{ ... first row data ... },{ ... second row data ... }] }} |
And, amazing coincidence, all these javascript libraries have a concept of a
(data)store that can handle this. Database paging with lazy loading, scrolling grids, you name it, it can be done ...
Except when the resultset contains only one row :
<RESULTS> <ROW> ... first row data ... </ROW> </RESULTS> |
This gets translated (or should I say transrepted ;-) to
Gets translated to
{"results": { "row": { ... first row data ... } }} |
Do you spot the difference ? I didn't, not at first. But why the hell did all those frameworks suddenly stop loading my data ? Before I give the solution, note that the above IS the correct - and most efficient - translation ...
The problem is that "row" is no longer a table. What is missing is []. And what do you know, all the frameworks expect a JSON table !
Ugly hackI made a small change to the JSONObject.java source which solves the problem for me. It is ugly (meaning it is not dynamic), but if it does the trick for me, maybe it will for you.
public JSONObject accumulate(String key, Object value) throws JSONException { testValidity(value); Object o = opt(key); if (o == null) { if (key.equals("row")) { put(key, new JSONArray().put(value)); } else { put(key, value); } } else if (o instanceof JSONArray) { ((JSONArray)o).put(value); } else { put(key, new JSONArray().put(o).put(value)); } return this; } |
And now the translation is :
{"results": { "row": [{ ... first row data ... }] }} |
Better HackI'm convinced that a good solution sits on the server (NetKernel) end, not on the javascript library side. A dynamic way to force the translator to handle certain xml tags slightly differently (but still within the JSON rules). Sort of like the array intervention in JSONToXML. Anyone up to the challenge ?
Enjoy,
Tom