PDA

View Full Version : Grid remains empty after store.load.



Rajat Sharma
24 Nov 2011, 5:54 AM
Hi
I am using ext 4 for getting data from server and loading into a simple grid. All i see is an empty grid after a couple of seconds taken in loading. I am a begginner and have managed this code from some basic examples. It does hit the server. I have checked. My java returns a JSONArray but still something is missing here. Infact, i saw 75 lines in grid, which are the number of values in my JSONArray. Is there any further decoding required? For loading, i am using store.load method.
please help.
var userStore = Ext.create('Ext.data.Store', {
model: 'User',

proxy: {
type: 'ajax',
url : 'ActionServlet?task=userList',
reader: {
type: 'json',
model: 'User'
}
}
});

tvanzoelen
24 Nov 2011, 6:06 AM
How does your JSON look like? Where is the data found?

Take the model out of your reader just set it in the store and define the root property there.



reader: {
type : 'json',
root : 'users',
totalProperty : 'total',
successProperty: 'success'
}

skirtle
24 Nov 2011, 6:15 AM
Check your JSON (Firebug and Chrome Developer Tools both have a JSON viewer for network traffic), check the fields on your model and check the dataIndex values on your columns. Make sure they all tie up.

Rajat Sharma
24 Nov 2011, 6:19 AM
Hi Tvanzoelen

Even I suspect that it has got something to do with JSON coming from server. But it is a simple JSONArray which is in the format {<object1>, <object2>, <object3>....}. I reall cannot understand what could be the problem here. I create this JSONArray from a string array so basically these objects are strings.
Googling suggested that Ext.decode is used in this context but if i go for that, i guess i will have to manually collect a result, decode it and then fill the grid, rather than using directly store.load.
Please guide if i am wrong somewhere. Also, kindly elaborate your second point.

skirtle
24 Nov 2011, 6:26 AM
You shouldn't need to decode it yourself. If you do it suggests you've got a problem with double-escaping. Please post a copy of the JSON so we can help you.

Rajat Sharma
24 Nov 2011, 6:32 AM
Hi Skirtle

Thanks for pointing that out. Under the network section of the dev tools, in the "content" tab, I see the complete string array that my server code sends. I am not sure if this is coming as a JSONArray. Where is this JSON viewer in dev tools.

skirtle
24 Nov 2011, 6:39 AM
The JSON viewer will only appear if the content is valid JSON. It may require a suitable content-type header too, I'm not sure. Your data is probably double-escaped, look for extra sets of quotes that shouldn't be there.

If you could post the response string here we could figure this out much faster.

Rajat Sharma
24 Nov 2011, 6:39 AM
Here is the humble code:


server side:
//extracting string values from a string array and putting into a JSONArray
//Assume it correct, i have tested it.


public JSONArray getUserJSON(){
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();
for(String val : userArray)
userJSON.add(val);
return userJSON;
}

client side:
//model
Ext.define('User', {
extend: 'Ext.data.Model',
fields: [ 'name' ]
});


Ext.onReady(function() {
//upon click of a DOM component


Ext.get('userLink').on('click', function(){
var userStore = Ext.create('Ext.data.Store', {
model: 'User',
proxy: {
type: 'ajax',
url : 'ActionServlet?task=userList',
reader: {
type: 'json',
model: 'User'
}
}
});


Ext.create('Ext.grid.Panel', {
renderTo: Ext.getBody(),
store: userStore,
width: 100,
height: 800,
title: 'Users',
columns: [
{
text: 'Name',
width: 100,
sortable: false,
hideable: false,
dataIndex: 'name'
}
]
});
userStore.load();
});
});

pardon me for not using the code tags. Please point out if there is anything wrong here. As i said, the array comes to client, as i checked in chrome dev tools. I see 75 (number of values in my array) empty rows in a dynamically created grid.

Rajat Sharma
24 Nov 2011, 6:42 AM
Double escaped as in ? For your reference this is what I see in dev tools' Network sections' Content tab:
basic format of the array received:

["glsextusr23","GLSEXTUSR36","XBBJVC0","XBBKBJC","glsextusr12","XBBJM1Q","GLSEXTUSR1717","ADCXFG2",.........and so on.....]

skirtle
24 Nov 2011, 6:45 AM
I don't understand why you aren't using CODE tags?

OK, the problem is that you are returning an array of strings like this:


["name1", "name2", "name3", ...]

whereas your reader is configured to handle a format like this:


[{"name": "name1"}, {"name": "name2"}, {"name": "name3"}, ...]

The easiest way to fix this is to tweak your server-side code.

tvanzoelen
24 Nov 2011, 6:49 AM
I think Skirtle is right.

For decoding JSON serverside,

what if you put your json values serverside through this function? I do it with my JSON



public static string JSONEncode(string stringToEncode)
{

string output = stringToEncode.Replace(@"\", @"\\");

output = output.Replace("'",@"\'");
output = output.Replace("\f", @"\\f");
output = output.Replace("\b", @"\\b");
output = output.Replace("\t", @"\\t");
output = output.Replace("\r", @"\\r");
output = output.Replace("\n", @"\\n");

return output;

}



its C# but else rebuild it into the language you use

Rajat Sharma
24 Nov 2011, 7:05 AM
Stupid as it may sound, can you provide some info/ link on how to create JSONArray in the way you have pointed. I was merrily creating it by direcly using add method.
As per my knowledge, a JSONArray can have multiple comma separated values. A value can be an object which is a name value pair.
what then could be the problem here. Any other way to programmatically create a JSONArray in desired way.


JSONArray userJSON = new JSONArray();
userJSON.add({"name":"value1"});

Rajat Sharma
24 Nov 2011, 7:11 AM
tvanzoelen

Ok so are you suggesting that before adding the values to the JSON array (which will eventually be String), i should first pass the string to some encoding function that changes it into the format which the client side code is configured to read. Something like:


"user" converted to "name": "user"
Have i understood you correctly. something like java.regex will have to be looked into for escaping the double quotes if that is the case.

tvanzoelen
24 Nov 2011, 7:12 AM
What is JSON array? Is it java? Then put in a java Object with a property name in it.

tvanzoelen
24 Nov 2011, 7:14 AM
If you use a java implementation that creates a JSON array it will probable do that for you. In that case you can forget about the encoding. Try to create a JSON string in the format Skirtle has pointed out.

Else try to use an ordinary StringBuilder.

Rajat Sharma
24 Nov 2011, 7:18 AM
Yes it is Java. Strangely enough, I am not able to construct a simple JSON array in the desired format. I already posted the add method way I am using. Based on my undertanding of what all can be possible values for JSON object and JSONArray. Still, there are syntax errors.

skirtle
24 Nov 2011, 7:22 AM
It depends exactly which JSON library you're using. It'll be something like this:


public JSONArray getUserJSON(){
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
userJSON.put(new JSONObject().put("name", val));
}

return userJSON;
}

tvanzoelen
24 Nov 2011, 7:22 AM
I am a bit out of java but this must work...if it is a proper JSON array implmentation.

Create a java class with one property called name

Create an instance of that class and give property name a value. Put that object (instance of that class) in that JSONArray add method.

stewardsencha
24 Nov 2011, 7:27 AM
Server output needs to be json-encoded.
Differently for same/cross domain too.
Maybe a php example will help.



$results=assoc array from mysql

$result= array(
'success' => true,
'count' => $count,
'results' => $results
);
$this->output($result);
...
function output($buff)
{
if ( $callback = $this->input->get('callback') )
{
header('Content-Type: text/javascript');
echo $callback . '(' . json_encode($buff) . ');'; // jsonP cross domain
}
else
{
header('Content-Type: application/x-json'); // same domain
echo json_encode($buff);
}
}

tvanzoelen
24 Nov 2011, 7:29 AM
Well the problem now is how to create a JSON array in java.:) Not in PHP.

We need java experts overhere.

Rajat Sharma
24 Nov 2011, 7:34 AM
Skirtle

with a minor modification, I used ur suggestion:

userJSON.add(new JSONObject().put("name", val));

There is infinite loading and the client side shows the error in dev tools in ext-all.js

Cannot read property 'name' of null

tvanzoelen
24 Nov 2011, 7:42 AM
Again, can you post the newly created JSON?

Rajat Sharma
24 Nov 2011, 7:51 AM
In accordance with the suggestion you gave, here is the newly created JSON. User is the class with a string variable "name".


public JSONArray getUserJSON(){
System.out.println("here");
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();
User user;
for(String val : userArray) {
user = new User();
user.name=val;
userJSON.add(user);
}


return userJSON;
}


Infinite loading is no more. But content in dev tools shows this:
[{},{},{},{},{},{},{},.......

tvanzoelen
24 Nov 2011, 7:54 AM
The same as with Skirtles solution. We have to see the output. What is that JSON array returning?

What kind of JSON is created with Skirtles solution? If that is not right then the class implementation is an option.

Rajat Sharma
24 Nov 2011, 8:01 AM
just tested the above class implementation approch at server side test client. This is the resultant JSONArray.
[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}......

with skirtle's approach i.e

public JSONArray getUserJSON(){
System.out.println("here");
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
userJSON.add(new JSONObject().put("name", val));
}


return userJSON;
}


the output array is:
[null,null,null,null,null,null,null.....

tvanzoelen
24 Nov 2011, 8:06 AM
Try


public JSONArray getUserJSON(){
System.out.println("here");
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
userJSON.add(new JSONObject().put("name", new String(val)));
}


return userJSON;
}

Rajat Sharma
24 Nov 2011, 8:10 AM
same as above:
[null,null,null,null,null,null,null.....

I guess it is time for some theoretical clarity on JSON. I had been avoiding it for too long.

tvanzoelen
24 Nov 2011, 8:29 AM
I think it must be JSONArray.put() instead of add



public JSONArray getUserJSON(){
System.out.println("here");
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
userJSON.put(new JSONObject().put("name", val));
}


return userJSON;
}


Another try



public JSONArray getUserJSON(){


JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
Map m = new HashMap();
m.put("name", val);
userJSON.put(m);
}


return userJSON;
}

[/CODE]

Rajat Sharma
24 Nov 2011, 8:41 AM
JSONArray.put() shows a syntax error. Perhaps i use different jars.

The second approach, however (to my joy and relief) generates:

[{"name":"value1"},{"name":"value2"},{"name":"value3"},{"name":"value4"},{"name":"value5"}......

It works at the client side resulting in my first ever working ext example.
Thanks to both of you for your time and effort. Skirtle diagnosed the problem correctly. If anyone can throw more light on the basics of the problems (which i guess is called Double escaping), i will be grateful.
Thanks once again.

skirtle
24 Nov 2011, 8:07 PM
The problem you had was not double-escaping. That was just an earlier theory, it proved to be incorrect. There wasn't actually anything wrong with your original JSON, it just wasn't the same format that the reader was expecting.

You never stated which JSON library you were using. I assumed you were using this one, but you're observations suggest otherwise:

http://www.json.org/java/index.html

Quite why you were getting nulls isn't clear, I suggest you take a look at the Java source for your library and try to understand what it was doing. Perhaps the put method on a JSONObject was returning the previous value for that key rather than the object itself, that would explain it. In that case, something like this might also work:


public JSONArray getUserJSON(){
JSONArray userJSON = new JSONArray();
String[] userArray = getuserArray();

for(String val : userArray) {
JSONObject user = new JSONObject();
user.put("name", val);
userJSON.add(user);
}

return userJSON;
}

Rajat Sharma
25 Nov 2011, 4:45 AM
Thanks Skirtle

It works indeed. So i guess in future i will have to carefully construct my JSON objects. Also, is there any API doc link for JSON which is irrespective of the impl jars I use. Thanks again.

skirtle
25 Nov 2011, 4:55 AM
JSON is a data serialization format comparable in purpose to XML. It isn't really meaningful to talk about an implementation agnostic API for JSON. In essence it is just a subset of JavaScript's literal syntaxes, excluding those which don't make sense for a generic data transfer format.

JSON is described here:

http://www.json.org/

It also includes several links to other resources.

Rajat Sharma
25 Nov 2011, 5:05 AM
Thanks for the explanation.