4

I have the below Json (wf.json)

{
"workflow":{
    "template":"Analysis1",

    "start":{
        "instance":"HDA_run1",
        "user":"symtest",
        "date":"3-Mar-2012",
        "timestamp":"1330948220475"
    },
    "host":{
        "name":"bartla",
        "user":"symtest1",
        "password":"symtest1",
        "installpath":"",
        "product":""
    },
    "javadump":{
        "pid":"8989",
        "corefilename":"",
        "heapdump":"",
        "stack":"",
        "JAVA_HOME":""  
    },
    "mat":{
    },
    "email":{
        "to":"ars@gmail.com",
        "subject":"",
        "message":""
    },
    "end":{
    }
}
}

As you can see there are 7 items (or sub headings inside main heading workflow). Under each item it can have another set of properties eg: email (item) has 3 properties ("name":"value").

So based on the number of properties I need to be able to create controls (Text) in my Flex 3 UI.

I read here that actionjson is 5-6x faster than the as3corelib, but I am not able to find any example code for it. The actionjson doc says it function the same way as corelib, so I even tried import com.adobe.serialization.json.JSON; JSON.decode(rawData) but it is unable to find JSON.

Below is my code

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" 
            layout="absolute" minWidth="955" minHeight="600"
            creationComplete="service.send()">

    <mx:Script>
    <![CDATA[

        import mx.controls.Alert;
        import mx.rpc.events.ResultEvent;

        private function onJSONLoad(event:ResultEvent):void
        {
            //get the raw JSON data and cast to String
            var rawData:String = String(event.result);
            //Alert.show(rawData); This prints my JSON String

            var obj:Object = decodeJson(rawData);   
            /*error call to possibly undefined method decodeJson*/
            Alert.show(obj.toString());
        }
    ]]>
    </mx:Script>

    <mx:HTTPService id="service" resultFormat="text"
                url="/cjb/wf.json"
                result="onJSONLoad(event)" />

</mx:Application>

Please help me fetch name, values if any from each item. Thanks

Is it not possible to directly fetch json data from an object (not custom made) like it is done in jquery?

Update with Flex Build Path

enter image description here

AabinGunz
  • 12,109
  • 54
  • 146
  • 218
  • 1
    The absolute fastest is native JSON parsing, but you must be able to target Flash Player 11. – RIAstar Mar 12 '12 at 12:50
  • @RIAstar: any links where I can read & does it mean it is only valid for Flash Player 11 & above? – AabinGunz Mar 12 '12 at 12:53
  • http://help.adobe.com/en_US/as3/dev/WS324d8efcab3b0d1e2408f9e3131fddffcfc-8000.html and yes, that's FP 11+ – RIAstar Mar 12 '12 at 12:56
  • @RIAstar: Thanks, after [reading this](http://help.adobe.com/en_US/as3/dev/WS324d8efcab3b0d1e2408f9e3131fddffcfc-8000.html#WSf3d65dd2c930a82b43322d12132a75d91da-8000), It seems that I need to create custom classes to hold the properties in it, but in my case I don't know the number of properties an item is having `(0 or more)`. So what will be my best option? – AabinGunz Mar 12 '12 at 13:30
  • You don't _have_ to create custom classes: the JSON.parse() method returns a dynamic object that you can use as is. – RIAstar Mar 12 '12 at 14:23
  • @RIAstar: Please if you could then help me with a small sample code to fetch things out of json using native json parsing? – AabinGunz Mar 14 '12 at 06:44
  • 1
    Come to think of it: Flex 3 comes with a playerglobal.swc that targets FlashPlayer 9. So you would either have to compile your Flex 3 app with the Flex 4.5 compiler or replace that playerglobal.swc with the one from the Flex 4.5 SDK. Is any of these approaches acceptable to you? – RIAstar Mar 14 '12 at 08:15
  • @RIAstar: Thanks for this information. I am using Flex 4 to compile Flex 3 app, but I need a sample code that can take a JSON string and get me keys & values, preferably using native Json parsing. I am not sure whether solution provided by DrogoNevets is native and even I am having some trouble with the code provided by him. I wrote some comment under his solution. – AabinGunz Mar 14 '12 at 08:59

4 Answers4

10

If the fastest parser is what you want, then you'll want use native JSON parsing. Its usage is as simple as this:

var result:Object = JSON.parse(event.result);
trace(result.workflow.template);  //traces "Analysis1"

The JSON class is located in the root package, so no need to import anything. You can find information on its usage in the docs.

However native JSON is only available for Flash Player 11 or higher, which means you'll have to target at least that player version. Since your compiling a Flex 3 application, it will target Flash Player 9 by default. If your requirements don't prohibit you from targeting FP11+, the easiest fix is to compile with the Flex 4.6 (or higher) SDK. The screenshot in your question shows that you're using Flex 3.5, so you'll have to change that in the "build path" settings.


If you wish to traverse the resulting object dynamically, you can do it with a simple 'for' loop:

//workflow is the root node of your structure
var workflow:Object = result.workflow;
//iterate the keys in the 'workflow' object
for (var key:String in workflow) {
    trace(key + ': ' + workflow[key]);
}
//template: Analysis1
//start: [Object]
//host: [Object]
//...

If you want to do it recursively, you can check whether a value is an Object or not:

if (workflow[key] is Object) {
    //parse that node too
}
else {
    //just use the value
}
RIAstar
  • 11,912
  • 20
  • 37
  • Thanks your comment works. I am afraid I have to stick with Flex 3 compiler, because my project is made in the same. So following your comment it gives me `Analysis1`, for `Alert.show(obj.workflow.template); Alert.show(obj.workflow.length()); Alert.show(obj.workflow[1]);` code, but later alerts don't seem to work. I wanted to get all the `keys` & `values` as I mentioned before, it's dynamic, and I don't know what keys and values the Json might contain. So may be some kind of traversal and i'll get all the keys. Is there a way? Thanks and sorry for, me being such a noob – AabinGunz Mar 14 '12 at 11:43
  • @AbhishekSimon I've added a dynamic traversal example to my answer. Also you can compile a Flex3 app with the Flex 4.6 compiler. You just have to be certain that your customer's requirements allow you to target FP 11 – RIAstar Mar 14 '12 at 12:17
  • Awesome.. exactly what i wanted. Thanks very nice information. – AabinGunz Mar 15 '12 at 05:48
  • just for the sake of other newbie's I am adding my answer, but credit goes to you :) – AabinGunz Mar 15 '12 at 05:56
2
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
    <![CDATA[
        import com.adobe.serialization.json.JSON;       
        [Embed(source="assets/test.json",mimeType="application/octet-stream")]
        private var json_file:Class;
        protected function button1_clickHandler(event:MouseEvent):void
        {           
            trace("Hello from Flex Debugging!");
            var bytes:ByteArray = new json_file();
            var json:String = bytes.readUTFBytes(bytes.length);
            trace(json);            
            var arr:Object = JSON.decode(json);
            for (var keyname:String in arr)
            {
                trace ( keyname + ": " + arr[ keyname ] );          
            }   
            grid.dataProvider = arr;
        }
    ]]>
</mx:Script>
<mx:DataGrid id="grid" right="10" left="10" top="10" bottom="10">
        <mx:columns>
            <mx:DataGridColumn headerText="Name" dataField="name"/>
            <mx:DataGridColumn headerText="Age" dataField="age"/>
        </mx:columns>
    </mx:DataGrid>
    <mx:Button x="538" y="45" label="Get Json" click="button1_clickHandler(event)"/>
</mx:WindowedApplication>

test.json

{ "name": "dibneg", "age" : "67", "sex": "female", "imagePath": "kamil.jpg" }

Dinesh
  • 566
  • 4
  • 16
1

After following solution from RIAstar, this is what I did (both Flex 3.5 compiler & 4.6 compiler code)

Flex 3.5 compiler using as3corelib.swc for JSON

import com.adobe.serialization.json.JSON;

private var temp:String ='{"workflow":{ "template":"HeapDumpAnalysis",      "start":{       "instance":"HDA_run1",      "user":"symtest",       "date":"3-Mar-2012",        "timestamp":"1330948220475" },  "host":{        "name":"estilo",        "user":"symtest1",      "password":"symtest1",      "installpath":"",       "product":""    },  "javadump":{        "pid":"8989",       "corefilename":"",      "heapdump":"",      "stack":"",     "INFA_HOME":""  },  "mat":{ },  "email":{       "to":"vsatwik@informatica.com",     "subject":"",       "message":""    },  "end":{ }}}';
private function test():void
{
    var obj = JSON.decode(temp);

    var workflow:Object = obj.workflow;
    for (var key:String in workflow) {
        trace(key + ': ' + workflow[key] + (key is String) + ", " + (workflow[key] is String));

    }
}

output

javadump: [object Object]true, false
template: HeapDumpAnalysistrue, true
host: [object Object]true, false
end: [object Object]true, false
mat: [object Object]true, false
email: [object Object]true, false
start: [object Object]true, false

Flex 4.6 compiler using native Json parsing

private var temp:String ='{"workflow":{ "template":"HeapDumpAnalysis",      "start":{       "instance":"HDA_run1",      "user":"symtest",       "date":"3-Mar-2012",        "timestamp":"1330948220475" },  "host":{        "name":"estilo",        "user":"symtest1",      "password":"symtest1",      "installpath":"",       "product":""    },  "javadump":{        "pid":"8989",       "corefilename":"",      "heapdump":"",      "stack":"",     "INFA_HOME":""  },  "mat":{ },  "email":{       "to":"ars@gmail.com",       "subject":"",       "message":""    },  "end":{ }}}';

private function test():void
{
    var result:Object = JSON.parse(temp);
    var workflow:Object = result.workflow;

    for (var key:String in workflow) {
        trace(key + ': ' + workflow[key] + (key is String) + ", " + (workflow[key] is String));

    }
}

output

javadump: [object Object]true, false
mat: [object Object]true, false
end: [object Object]true, false
email: [object Object]true, false
host: [object Object]true, false
start: [object Object]true, false
template: HeapDumpAnalysistrue, true
AabinGunz
  • 12,109
  • 54
  • 146
  • 218
0
import com.adobe.serializers.json.JSONDecoder;

var JSON:JSONDecoder = new JSONDecoder();
var result:Object = JSON.decode(JSON_STRING);

that worked for me then you can either construct new object type(s) or jsut access values either

result.template

or

result['template']

the latter is good for dynamic valus/keys needed rather than known key values

DrogoNevets
  • 1,456
  • 3
  • 18
  • 34
  • I used `import com.adobe.serialization.json.JSONDecoder; var obj = JSON.decode(event.result.toString()); Alert.show(obj.template);` but i gives me empty alert box – AabinGunz Mar 14 '12 at 05:20
  • Also is it native JSON parsing? – AabinGunz Mar 14 '12 at 06:08
  • 1
    @AbhishekSimon No it's not and neither is it 'actionjson'. This is the one from 'as3corelib' which you seek to replace. – RIAstar Mar 14 '12 at 10:38
  • 1
    @AbhishekSimon And that alert isn't showing anything because you need to access that value through `result.workflow.template` instead of `result.template`. Not an answer to the question _and_ a mistake: -1 – RIAstar Mar 14 '12 at 10:40