[plugin] JSON (import/export/generate/edit/inspect/...)

Post your work in progress addons and get feedback

Post » Thu Jul 31, 2014 1:07 pm

@Yann, I'm here again, i tried creating the sample json you used for the inspection capx with the plugin and i'm having some issues.
In a bit to achieve the nested array and objects, when i get to the debug mode somethings my json is just empty. what i'm I doing wrong? My sample capx is here
You do not have the required permissions to view the files attached to this post.
B
15
S
4
Posts: 138
Reputation: 2,003

Post » Fri Aug 01, 2014 5:39 am

@Dasat
If you run the capx in the debugger (Ctrl+F5) you should see that:
Code: Select all
{
  "name": "dasat",
  "properties": {
    "property_name": "thermal"
  }
}

which is not nothing, but yeah, not what you want for now

Let's comment what you did line by line so I explain a few things:

Code: Select all
+ System: on start of layout
   // in javascript it could be represented as: var root = {};
   -> JSON: new Object at [email protected]   
   + [empty]
      // here you are redoing: root = {}; which basically discard the first object
      -> JSON: new Object at [email protected]
      // here current and root are the same, so you are doing:  root["name"] = "Dasat";
      -> JSON: set "Dasat" at [email protected]"name"
      // you set the current path to the current path, so nothing changes
      -> JSON: Set Current Path to [email protected] 
      // here you do root["properties"] = [];
      -> JSON: new Array at [email protected]
      // here that make sens, now current is root["properties"]
      -> JSON: Set Current Path to [email protected]"properties"
      // you do root["properties"] = {}; so your array gets discarded
      -> JSON: new Object at [email protected] 
      // root["properties"]["property_name"] = "electrical"
      -> JSON: set "electrical" at [email protected]"property_name"
      // root["properties"]["property_unit"] = "wareva"
      -> JSON: new "wareva" at [email protected]"property_unit"
      // here you basically discard the object at root["properties"] and replace it by an empty one
      -> JSON: new Object at [email protected]
      // root["properties"]["property_name"] = "thermal"
      -> JSON:  new "thermal" at [email protected]"property_name"

To summurize I'll write in javascript only what you did
Code: Select all
var root = {};
root = {};     //which basically discard the first object
root["name"] = "Dasat";
root["properties"] = [];
root["properties"] = {}; // discard the array
root["properties"]["property_name"] = "electrical";
root["properties"]["property_unit"] = "wareva";
root["properties"] = {}; // discard the previous object
root["properties"]["property_name"] = "thermal";

So here the result showing in the debugger makes sens

Let's travel from javascript back to the JSON plugin
What you want to generate is:


I'm trying to have something like let's build a basic addition and multiplication table, like what we learnt whe we were young (but yeah, 0-based for simplicity):
Code: Select all
[
   {"name": "dasat,
    "properties": [
          {"property_name": "conductivity", "property_unit": "wareva" },
          {"property_name": "restitivity", "property_unit": "ohmmeter"}
      ]
   },
   {"name": "dasat2,
   "properties":[
         {"property_name": "conductivity2", "property_unit": "wareva2" }
         {"property_name": "restitivity2", "property_unit": "ohmmeter2"}
      ]
   }
]


in javascript you can do it like that:
Code: Select all
var root = [];
root[0] = {};
root[0]["name"] = "Dasat";
root[0]["properties"] =  [];
root[0]["properties"][0] =  {};
root[0]["properties"][0]["property_name"] = "conductivity";
root[0]["properties"][0]["property_unit"] = "wareva";
root[0]["properties"][1] =  {};
root[0]["properties"][1]["property_name"] = "restitivity";
root[0]["properties"][1]["property_unit"] = "ohmmeter";
root[0] = {};
root[1]["name"] = "Dasat2";
root[1]["properties"] =  [];
root[1]["properties"][0] =  {};
root[1]["properties"][0]["property_name"] = "conductivity2";
root[1]["properties"][0]["property_unit"] = "wareva2";
root[1]["properties"][1] =  {};
root[1]["properties"][1]["property_name"] = "restitivity2";
root[1]["properties"][1]["property_unit"] = "ohmmeter2";


Some equivalents with the JSON plugin would be:
JSONDasat.capx
Last edited by Yann on Sun Sep 14, 2014 8:41 pm, edited 1 time in total.
B
68
S
22
G
14
Posts: 1,485
Reputation: 16,561

Post » Fri Aug 01, 2014 4:07 pm

@Yann,
Wow, you are a good teacher!!!, at the beginning i was feeling dumb realizing what i was actually doing, but i think i have a better understanding now.
But, for the capx you sent, in the third method, if you check the debugger you would see its only adding the first property object and not the second, also, if you don't mind i would appreciate you shedding light also on retriving values by using the json.value expression:
i expect setting text to json.value(0,"path","to","an","object") to spilll out all the contents of the object, or adding a key after the object to return the value of the key, but i keep getting undefined, when i attempt this


Yann wrote:@Dasat
If you run the capx in the debugger (Ctrl+F5) you should see that:
Code: Select all
{
  "name": "dasat",
  "properties": {
    "property_name": "thermal"
  }
}

which is not nothing, but yeah, not what you want for now

Let's comment what you did line by line so I explain a few things:

Code: Select all
+ System: on start of layout
   // in javascript it could be represented as: var root = {};
   -> JSON: new Object at [email protected]   
   + [empty]
      // here you are redoing: root = {}; which basically discard the first object
      -> JSON: new Object at [email protected]
      // here current and root are the same, so you are doing:  root["name"] = "Dasat";
      -> JSON: set "Dasat" at [email protected]"name"
      // you set the current path to the current path, so nothing changes
      -> JSON: Set Current Path to [email protected] 
      // here you do root["properties"] = [];
      -> JSON: new Array at [email protected]
      // here that make sens, now current is root["properties"]
      -> JSON: Set Current Path to [email protected]"properties"
      // you do root["properties"] = {}; so your array gets discarded
      -> JSON: new Object at [email protected] 
      // root["properties"]["property_name"] = "electrical"
      -> JSON: set "electrical" at [email protected]"property_name"
      // root["properties"]["property_unit"] = "wareva"
      -> JSON: new "wareva" at [email protected]"property_unit"
      // here you basically discard the object at root["properties"] and replace it by an empty one
      -> JSON: new Object at [email protected]
      // root["properties"]["property_name"] = "thermal"
      -> JSON:  new "thermal" at [email protected]"property_name"

To summurize I'll write in javascript only what you did
Code: Select all
var root = {};
root = {};     //which basically discard the first object
root["name"] = "Dasat";
root["properties"] = [];
root["properties"] = {}; // discard the array
root["properties"]["property_name"] = "electrical";
root["properties"]["property_unit"] = "wareva";
root["properties"] = {}; // discard the previous object
root["properties"]["property_name"] = "thermal";

So here the result showing in the debugger makes sens

Let's travel from javascript back to the JSON plugin
What you want to generate is:


I'm trying to have something like let's build a basic addition and multiplication table, like what we learnt whe we were young (but yeah, 0-based for simplicity):
Code: Select all
[
   {"name": "dasat,
    "properties": [
          {"property_name": "conductivity", "property_unit": "wareva" },
          {"property_name": "restitivity", "property_unit": "ohmmeter"}
      ]
   },
   {"name": "dasat2,
   "properties":[
         {"property_name": "conductivity2", "property_unit": "wareva2" }
         {"property_name": "restitivity2", "property_unit": "ohmmeter2"}
      ]
   }
]


in javascript you can do it like that:
Code: Select all
var root = [];
root[0] = {};
root[0]["name"] = "Dasat";
root[0]["properties"] =  [];
root[0]["properties"][0] =  {};
root[0]["properties"][0]["property_name"] = "conductivity";
root[0]["properties"][0]["property_unit"] = "wareva";
root[0]["properties"][1] =  {};
root[0]["properties"][1]["property_name"] = "restitivity";
root[0]["properties"][1]["property_unit"] = "ohmmeter";
root[0] = {};
root[1]["name"] = "Dasat2";
root[1]["properties"] =  [];
root[1]["properties"][0] =  {};
root[1]["properties"][0]["property_name"] = "conductivity2";
root[1]["properties"][0]["property_unit"] = "wareva2";
root[1]["properties"][1] =  {};
root[1]["properties"][1]["property_name"] = "restitivity2";
root[1]["properties"][1]["property_unit"] = "ohmmeter2";


Some equivalents with the JSON plugin would be:
https://dl.dropboxusercontent.com/u/23551572/C2/JSONDasat.capx
B
15
S
4
Posts: 138
Reputation: 2,003

Post » Fri Aug 01, 2014 6:48 pm

@Dasat,
Ah, indeed, I made a mistake, I corrected it, if you download the capx again you should see the change. I leave you, as an exercise, to find out why it was broken.
Also it reminded me about two things:
1/ Use the console log, on preview mode I print useful warnings when something is wrong (like trying to assign a value to an inexisting path)
2/ The LogData action logs interesting information in the console. (See the aforementioned correction for a usage example)

As far as the Value expression goes, it should be almost straight forward. With only one small little ugly thing: to retrieve a value, you need to specify the path of that value. And my plugin has support for absolute path (from root) or relative path (from current).
The problem is that in an expression you can only use numbers and strings. So the only solution I found was to use the first argument of value to be 0 for root and 1 for current.
This way, if you put something a:
Code: Select all
[email protected],"property",1,"property_name"
You can retrieve it using
Code: Select all
JSON.Value(0, 0,"property",1,"property_name")
 means root^  ^-------absolute path--------^

with relative path:
Code: Select all
Set Current Path at [email protected],"property",1
[email protected]"property_name"

corresponds to

JSON.Value(1,"property_name")
   current ^ ^relative path^


The Size expression follows the same rule, it returns the number of element in an array or the number of member in an object, for other types, if my memory is correct it will return -1
B
68
S
22
G
14
Posts: 1,485
Reputation: 16,561

Post » Fri Aug 01, 2014 7:28 pm

@Yann, the capx on foreachproperty
You do not have the required permissions to view the files attached to this post.
B
15
S
4
Posts: 138
Reputation: 2,003

Post » Fri Aug 01, 2014 8:23 pm

@Yann, the jsonDasat capx is still not updated
B
15
S
4
Posts: 138
Reputation: 2,003

Post » Fri Aug 01, 2014 9:07 pm

@Dasat
Ah yeah sorry I forgot to launch dropbox, now it's updated

And for your foreach, first, remember to not do it every tick, that's the reason why it wasn't stopping. You can nest it under the start of layout event for it to just run once.

Now as far as foreach goes, you're using it correctly.
However, you have two ways to loop through arrays:
- foreach as you did
- "index looping", basically go from 0 to the size of the array-1 and use loopindex in the path to look up the values (that's actually what is usually done in common programming)

The two mecanisms have a slightly different behaviour that can be seen in this capx: JSONDasat-holy-array.capx

As far as I could test, the foreach keeps the proper array ordering.
Looping using foreach is like considering the array as an object. And objects have no intrinsic ordering. So the foreach keeping the ordering shouldn't be expected, even if, it seems that does it, at least on chrome....
I dunno if it's consistent throughout all the browsers, so I usually use index looping.

Now your other problem is that you're printing the keys using JSON.CurrentKey, if you want the content, you need to use JSON.CurrentValue
In your case, the value for "friends" is an array, so you need to detect that, you can either use the Is Array condition or check if CurrentKey = "friends".
I would personally check for Array 'cause this way you can change the name of the field if you need it.

Anyway, it should look something like that JSONDasat-foreach.capx
Last edited by Yann on Sun Sep 14, 2014 8:40 pm, edited 2 times in total.
B
68
S
22
G
14
Posts: 1,485
Reputation: 16,561

Post » Fri Aug 01, 2014 9:10 pm

@Yann, thanks a lot, I'm already making progress with the project, i really appreciate you.
Yann wrote:@Dasat
Ah yeah sorry I forgot to launch dropbox, now it's updated

And for your foreach, first, remember to not do it every tick, that's the reason why it wasn't stopping. You can nest it under the start of layout event for it to just run once.

Now as far as foreach goes, you're using it correctly. The only thing that you should be aware of, it that using a foreach on an array could lead to weird results, 'cause the foreach won't insure that you'll loop through the indices in the proper order. When you use foreach on an array, the array is considered as an object and the number as fields. As if you had:
Code: Select all
{
   "0": "first",
   "1": "second",
   "2": "third",
   "3": "fourth"
}


usually with arrays I just loop through the indices
So your capx would look like this:
Code: Select all
+ System: repeat JSON.Size(0)
    -> JSON: set Current Path to [email protected]
    + JSON: foreach property at [email protected]
      -> Text: Append JSON.CurrentKey&newline  // newline makes it easier to read


Now your other problem is that you're printing the keys using JSON.CurrentKey, if you want the content, you need to use JSON.CurrentValue
In your case, the value for "friends" is an array, so you need to detect that, you can either use the Is Array condition or check if CurrentKey = "friends".
I would personally check for Array 'cause this way you can change the name of the field if you need it.

Anyway, it should look something like that https://dl.dropboxusercontent.com/u/23551572/C2/JSONDasat-foreach.capx
B
15
S
4
Posts: 138
Reputation: 2,003

Post » Fri Aug 01, 2014 9:26 pm

@Dasat,
I edited the bits about array looping since it wasn't entirely exact.
B
68
S
22
G
14
Posts: 1,485
Reputation: 16,561

Post » Mon Aug 04, 2014 3:50 am

When will this plugin to be a completed one? i.e. move to the section of Completed Addons
B
109
S
27
G
277
Posts: 4,482
Reputation: 154,924

PreviousNext

Return to Work in Progress Addons

Who is online

Users browsing this forum: No registered users and 0 guests