as3corelib JSON parsing problem - json

I have the following two routines in Flash Builder:
public function getData():void {
httpService = new HTTPService();
httpService.url = "https://mongolab.com/api/1/databases/xxx/collections/system.users/?apiKey=xxx";
httpService.resultFormat = HTTPService.RESULT_FORMAT_TEXT;
httpService.addEventListener(ResultEvent.RESULT, resultHandler);
httpService.send();
}
public function resultHandler(event:ResultEvent):void {
var rawData:String = String(event.result);
var arr:Array = JSON.decode(rawData) as Array;
Debug.log(rawData);
Debug.log(arr);
httpService.removeEventListener(ResultEvent.RESULT, resultHandler);
}
rawData is displayed as JSON data but arr is displayed as [object Object] rather than an array.
What am I doing wrong?

this
var jsonStr:String = '{"glossary": {"title": "example glossary","GlossDiv": {"title": "S"},"GlossSee": "markup"}}';
will be parsed and JSON.decode returns an Object and you can access the attributes like this:
var obj:* = JSON.decode(jsonStr);
trace(obj.glossary);
this
var jsonStr:String = '[{"title":"asd"},{"title":"asd"},{"title":"asd"},{"title":"asd"}]';
will be parsed and returns an Array (which if you trace it, will return [object Object]).
so if you don't know what data is returned you could just check if
var result:* = JSON.decode(jsonStr);
if (result.length != undefined) {
// array
var arr:Array = result as Array;
}
else {
// object
var obj:Object = result as Object;
}
a try/catch around decode would also be good, because you don't know if the jsonStr is well-formed...
cheers

Related

Convert a javascript array to specific json format

I have this JSON.stringify(array) result: ["id:1x,price:150","id:2x,price:200"] and I have to convert it in a json format similar to this (it would be sent to php):
[{
"id":"1x",
"price":150
},
{
"id":"2x",
"price":200
}]
Please help.
You can convert the structure of your data before using JSON.stringify, for example you can convert the data to a list of objects like so:
var strItems = ["id:1x,price:150", "id:2x,price:200"];
var objItems = [];
for (var i = 0; i < strItems.length; i++) {
var pairs = strItems[i].split(",");
objItems.push({
id: pairs[0].split(':')[1],
price: parseInt(pairs[1].split(':')[1])
});
}
Before calling JSON.stringify to get the result you're after:
var json = JSON.stringify(objItems);
console.log(json);
JSON.stringify(array) only does on layer, but you can change the stringify function to work for multiple layers with this function written by JVE999 on this post:
(function(){
// Convert array to object
var convArrToObj = function(array){
var thisEleObj = new Object();
if(typeof array == "object"){
for(var i in array){
var thisEle = convArrToObj(array[i]);
thisEleObj[i] = thisEle;
}
}else {
thisEleObj = array;
}
return thisEleObj;
};
var oldJSONStringify = JSON.stringify;
JSON.stringify = function(input){
if(oldJSONStringify(input) == '[]')
return oldJSONStringify(convArrToObj(input));
else
return oldJSONStringify(input);
};
})();
Once you have declared this, then you can call JSON.stringify(array)

actionscript 3 JSON failed to parse data

I have received a JSON data like this:
'{"result":[[["test","test"],["test","test"]],[],[],[]]}'
OR
'{"result":[
[
["test","test"],
["test","test"]
],
[],
[],
[]
]
}'
But when I try to JSON.parse(data);, it is converted to object like this:
{[[["test","test"],["test","test"]],[],[],[]]:}
Is there anyway to fix it?
ADDITIONAL:
i have traced what happen before,during,after JSON do, and the problem seems to be the parse itself, sometime it work, some time doesn't
var object:Object = {test:[[["Test","test1"],["test2"]],["test3"],[],[]]}
var stringed:String = JSON.stringify(object);
trace(stringed)//{"test":[[["Test","test1"],["test2"]],["test3"],[],[]]}
var backed:Object = JSON.parse(stringed);
for each(var thigng:String in backed){
trace(thigng, "=", backed[thigng])//Test,test1,test2,test3,, = undefined
}
var object:Object = {"test":"test3"}
var stringed:String = JSON.stringify(object);
trace(stringed)//{test:"test3"}
var backed:Object = JSON.parse(stringed);
for each(var thigng:String in backed){
trace(thigng, "=", backed[thigng])//test3 = undefined
}
A "for each...in" loop will only give you the value not the key.
What you need is the for in loop.
As you can see from the example below where you went wrong
var object:Object = {"this_is_the_key":"VALUE"}
var stringed:String = JSON.stringify(object);
var backed:Object = JSON.parse(stringed);
for each(var thigng:String in backed){
trace('KEY:', thigng, ' VALUE:' ,backed[thigng]) // KEY: VALUE VALUE: undefined
}
trace('------')
for(thigng in backed){
trace('KEY:', thigng, ' VALUE:' ,backed[thigng]) //KEY: this_is_the_key VALUE: VALUE
}
Also this is not a valid JSON string
'{"result":[[["test","test"],["test","test"]],[],[],[]]}'

need help recursive javascript function

I want to turn json string
treeNodes =[{managerid:root,Employeeid:01},
{managerid:01,Employeeid:11},
{managerid:01,Employeeid:22},
{managerid:22,Employeeid:33},
{managerid:22,Employeeid:44}];
into this json string using javascript.
json={
id:root,
children[{
id:01,
children[
{id:11},
{id:22}
]},
{
id:22,
children[
{id:33},
{id:44}
]
}
Can someone help with java script function?
I think you need something like this (I assume root is a declared variable):
var rootNode = {Employeeid:root};
var json = makeJsonNode(treeNodes, rootNode);
// Do something with "json"
// ...
function makeJsonNode(treeNodes, node){
var jsonNode = { id : node.Employeeid };
var children = [];
for(var i=0; i<treeNodes.length; i++){
if(treeNodes[i].managerid === node.Employeeid){
children.push(makeJsonNode(treeNodes, treeNodes[i]));
}
}
if (children.length > 0) jsonNode.children = children;
return jsonNode;
}

Access array element by string in AS3

As we know its possible to access field by name using indexer.
var obj:* = {name:"Object 1"};
trace(obj["name"]); // "Object 1"
But how to access an array element by String?
var arr:Array = new Array();
var obj:* = {items:arr};
trace(obj["items[0]"]); // Undefined
Ok, basically you want to be able to have a string be interpreted as actionscript. No elegant solution I'm afraid. You could write a parser that handles some simple syntax in a string and retrieves the value.
Here's a simple example:
var obj:Object = {
items:[1, 2, 3],
subObj: {
subitems: [4, 5, 6]
}
};
trace(getValueInObject(obj, "items[0]")); // 1
trace(getValueInObject(obj, "subObj.subitems[2]")); // 6
// takes an object and a "path", and returns the value stored at the specified path.
// Handles dot syntax and []
function getValueInObject(obj : Object, pathToValue : String) : * {
pathToValue = pathToValue.replace(/\[/g, ".").replace(/]/g, "");
var pathFractions : Array = pathToValue.split(".");
var currentObject : Object = obj;
while (pathFractions.length > 0 && currentObject != null) {
var fraction : String = pathFractions.shift();
currentObject = currentObject[fraction];
}
if (currentObject != null) {
return currentObject;
}
return null;
}

Reverse engineering - Flash app

I have that code:
private function handleFlashVarsXmlLoaded(event:Event) : void
{
var secondsplit:String = null;
var item:Array = null;
var string:* = XML(String(event.target.data));
var notsplited:* = string.vars_CDATA; //what is .vars_CDATA?
var splitted:* = notsplitted.split("&");
var datacontainer:Object = {};
var index:Number = 0;
item = secondsplit.split("=");
datacontainer[item[0]] = item[1];
this.parseFlashVars(datacontainer); // go next
return;
}
That function is loaded when URLLoader is loaded.
I think that this function parse a XML file to string(fe. param1=arg1&param2=arg2), then split it by "&" and then by "=" and add data to datacontainer by
datacontainer["param1"] = "arg1"
But how should the XML file look like and what is string.vars_CDATA
I think, vars_CDATA is just a name of XML field, becourse variable named "string" is contains whole XML. So var "notsplited" contains a String-typed data of this field (I think so, becourse of the line "var splitted:* = notsplitted.split("&");", which splits String to Array).