Helpful Information
 
 
Category: Apache Flex
Flex and JSON.decode woes

I am having some trouble getting the JSON.decode() method working.

I currently have the following JSON file in UTF-8 format:

{"states":[{"id":140,"state":"Alabama","obama":6,"mccain":5,"ec":3},
{"id":91,"state":"Alaska","obama":4,"mccain":5,"ec":3}],
"USA":{"obama":7450, "mccain":7450}
}

I am accessing it in Flex with the following code:

<mx:Script>
private function onJSONLoad(event:ResultEvent):void
{
var rawData:String = String(event.result);
var countries:Array = (JSON.decode(rawData) as Array);

Alert.show(countries.length as String);
var dp:ArrayCollection = new ArrayCollection(arr);

}
]]>
</mx:Script>

<mx:HTTPService
id="service"
resultFormat="text"
fault="faultHandler(event)"
url="http://localhost/gec/vote.json"
result="onJSONLoad(event)"
showBusyCursor="true" />

However, for the life of me, I cannot get Flex to correctly parse the JSON code into an array. In the line:

var countries:Array = (JSON.decode(rawData) as Array);

The countries array never gets populated with any of the data from the JSON file, even though the contents of the rawData variable correctly contain all the JSON code. And whenever I try to access the countries array, I receive the following error message:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

What am I doing wrong? Can someone point me in the right direction? Is there a problem with the JSON code structure? Is there something remarkably stupid I am overlooking? Hope someone can help me look at this with a fresh pair of eyes and see if they can spot the problem, because I have really hit a wall here.

Help me Obi-wan, you're our only hope!! I have been working on this problem for the past two days and really don't know where else to turn to for help!

Many thanks!

Phil

Hi stinkytofu, did you find a solution to this as i am having the same problem. turning into an array is bringing up an error..


cheers

chris

You don't need to cast it to an array, really. Here is how I did it:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onLoad()">

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.*;
import com.adobe.serialization.json.JSON;
import mx.controls.Alert;
import mx.utils.*;

[Bindable] private var dp:ArrayCollection = new ArrayCollection();
[Bindable] private var dp2:ArrayCollection = new ArrayCollection();

private function onLoad():void
{
//trace('sending service call');
service.send();
}

private function onJSONLoad(event:ResultEvent):void
{
//trace('got a result from service');
var countries:Object = JSON.decode(event.result as String);
for(var i:String in countries['states'])
{
dp.addItem(countries['states'][i]);
}

for(var j:String in countries['USA'])
{
var temp:Object = new Object();
temp.name = j;
temp.value = countries['USA'][j];
dp2.addItem(temp);
}
}

private function faultHandler(event:FaultEvent):void
{
trace('Fault generated. Error info: ' + ObjectUtil.toString(event));
}
]]>
</mx:Script>

<mx:HTTPService
id="service"
resultFormat="text"
fault="faultHandler(event)"
url="http://localhost/gec/vote.json"
result="onJSONLoad(event)"
showBusyCursor="true" />

<mx:HBox>

<mx:DataGrid dataProvider="{dp}"
editable="false">
<mx:columns>
<mx:DataGridColumn dataField="id" />
<mx:DataGridColumn dataField="ec" />
<mx:DataGridColumn dataField="mccain" />
<mx:DataGridColumn dataField="obama" />
<mx:DataGridColumn dataField="state" />
</mx:columns>
</mx:DataGrid>

<mx:Spacer width="50" />

<mx:DataGrid dataProvider="{dp2}"
editable="false">
<mx:columns>
<mx:DataGridColumn dataField="name" />
<mx:DataGridColumn dataField="value" />
</mx:columns>
</mx:DataGrid>

</mx:HBox>
</mx:Application>

I had to change the format of the "USA" section because it's using strings for keys instead of numerical indexes like the "states" section.

Note that you need the as3corelib library from here (http://code.google.com/p/as3corelib/), because Flex doesn't handle JSON natively.

I'm trying to do the same thing, and I tried implementing your code. Here's what mine looks like:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onLoad()">

<mx:Script>
<![CDATA[
import mx.events.CollectionEvent;
import mx.collections.ArrayCollection;
import mx.rpc.events.*;
import com.adobe.serialization.json.JSON;
import mx.controls.Alert;
import mx.utils.*;
import com.adobe.serialization.json.JSONDecoder;

[Bindable] private var dp:ArrayCollection = new ArrayCollection();

private function onLoad():void
{
//trace('sending service call');
service.send();
}

private function onJSONLoad(event:ResultEvent):void
{
//trace('got a result from service');

var countries:Object = JSON.decode(event.result as String);
for(var i:String in countries['layers'])
{
dp.addItem(countries['layers'][i]);

}
}



private function faultHandler(event:FaultEvent):void
{
trace('Fault generated. Error info: ' + ObjectUtil.toString(event));
}
]]>
</mx:Script>

<mx:HTTPService
id="service"
resultFormat="text"
fault="faultHandler(event)"
url="http://orthogonal.esri.com/restlegends/?soapUrl=http%3A%2F%2F142.176.0.171%3A8080%2FArcGIS%2Fservices%2FAnnapolis_Misc%2FMapServer&amp;f=pjson"
result="onJSONLoad(event)"
showBusyCursor="true" />

<mx:HBox>

<mx:DataGrid dataProvider="{dp}"
editable="false">
<mx:columns>
<mx:DataGridColumn dataField="layerId" />
<mx:DataGridColumn dataField="label" />
<mx:DataGridColumn dataField="url" />

</mx:columns>
</mx:DataGrid>

</mx:HBox>
</mx:Application>

And here's the data I'm trying to put into the datagrid:

{"layers": [
{
"layerId": 0,
"layerName": "Proposed Mains",
"legend": [{
"label": "One Year",
"url": "http://sampleserver1a.arcgisonline.com/templateoutput/_ags_leg3d4720bb3b0d41e89ae1682ffda2af67.png"
}]
},
{
"layerId": 1,
"layerName": "Scheduled Replacement Mains",
"legend": [
{
"label": "2009",
"url": "http://sampleserver1a.arcgisonline.com/templateoutput/_ags_leg66232cc6bc754a86a9786d7906da4d7a.png"
},
{
"label": "2010",
"url": "http://sampleserver1a.arcgisonline.com/templateoutput/_ags_leg2a2518115c144811a3736c9786425a95.png"
},
{
"label": "2011",
"url": "http://sampleserver1a.arcgisonline.com/templateoutput/_ags_legb0df04f6006844dd8d3bcadfc5e75c42.png"
},
{
"label": "2012",
"url": "http://sampleserver1a.arcgisonline.com/templateoutput/_ags_leg4bc8d2351740407cb2e723ce30015972.png"
}
]
},


How can I point to the layerId, label and url? Thanks for your help.

Mark










privacy (GDPR)