by Ryan Webber
[IMPORTANT NOTE: Since this article was written, we've created two actors dedicated to parsing and creating JSON; please visit the knowledge base for these actors first, as they should make the need to use the Javascript actor redundant.]
This tutorial covers an advanced topic and assumes you are familiar with the Isadora patching environment. Additionally you should have worked with the Javascript actor previously and completed the tutorial on loading external data with Javascript.
Here we will discover a method of using the Javascript actor in Isadora to facilitate the passing of multiple values between actors as text strings. These text strings will be JSON-formatted data and require Javascript actors on both ends to combine and divide the values.
Passing values this way is more complex than using the built-in Isadora data types; however, when creating complex scenes, where similar data sets are connected again and again in a repetitive manner, this method of bundling data can save a lot of time.
Combine multiple inputs into a JSON string
Combining the input values in a Javascript actor is very simple. Javascript comes with a built-in function that takes an array of values and formats them as a JSON string. This allows us to use the standard inputs of the Javascript actor to input up to 500 values. It's interesting to know that this limit of 500 is very flexible since each input can be another JSON string of many values.
Follow these steps to set up the data input section:
- Open Isadora, and save your file as "JSONstrings.izz"
- Add a Javascript actor to your Scene Editor.
- Double click the Javascript actor to open the Javascript Editor.
- Enter the following Javascript code and click OK to close the Javascript Editor.
function main() // required function
{
// wrap and return the provided arguments
// as a JSON formatted string
return JSON.stringify(arguments);
}
This short Javascript function is all that is required to return all the input values provided as JSON formatted text.
In Javascript we are provided with a built-in JSON object that offers a number of functions. Here we have called the stringify function from the JSON object using dot notation.
The returned data will be text, so we need to mutate the 'output1' output by connecting it to a text input. Add a Trigger Text actor to your patch and connect output1 to the input of the Trigger Text actor. Adjust the width of the Trigger Text input to allow viewing more of the text from the Javascript actor.
Now test the patch by adjusting the number of inputs to the Javascript actor, and setting values for each. Notice the value of output1 is a JSON object represented as text. It starts and ends with curly brackets: while its contents are key-value pairs (often referred to as name value pairs).
Enter "0.3" as the input value for input 1 of the Javascript actor. This value is output in our JSON text as "0.30000001192092896". This is due to the way floating point numbers are handled by computers.
You can read more about numbers in Javascript here, the article includes some hints on managing these differences. For our purposes, the numbers are close enough, and will not cause a problem in our Isadora work.
Divide JSON formatted text into separate values
Taking the JSON formatted text and breaking it down is a little more difficult. We are going to look at a simple loop method of solving this problem. It involves writing a loop in Javascript that will take each top-level item in the JSON text and add it to an array that is returned.
Add a new Javascript actor to your Isadora patch, and double-click it to open the Javascript Editor. Replace the default code with the following code.
function main()
{
// convert arguments[0] text input into JSON format
// and assign to variable
var parsed = JSON.parse(arguments[0]);
var array = [];// create empty array
// loop thru top level elements of variable parsed
for (elem in parsed ) {
// add current element of parsed to the end of the array
array.push(parsed [elem]);
}
// make the first output value a count of
// additional outputs needed
array.unshift(array.length);
// output our array to create
// an actor output for each value
return array;
}
Let's examine the code above.
The first line of code within the main() function creates a new variable named "parsed" and assigns its value to the value returned by a function call. The function call is to JSON.parse(), and passes the first value in our arguments array to the function. We pass the first value because we will connect our JSON text to input 1 of this Javascript actor.
JSON.parse() creates a Javascript object from the text string in argument[0]. This object is understood by Javascript, but if it is returned from the main() function it will not cause an error, but will not provide us any useful data values (try this to see what is output).
The second line creates a variable named "array" and sets it to an empty array. It's important here to notice that we could have used another name such as "arr" for the array. If we had used "arr" we would then later reference the array as "arr".
The third line starts a for loop. The loop will run the code within its curly brackets for each top-level item in the newly created "parsed" object as "elem".
Note: Top-level items in our input string will be comma separated. They can include complex data types like Arrays and JSON. The included image below shows how JSON data can be used as an input to our grouping script, and then later ungrouped. A second ungroup actor could be added to the patch to then split the second level of output data.
The next line of code is the only code contained in the for loop. This line of code adds the "elem" item to the end of the "parsed" array using a built-in array.push() function.
Note: If we had named our array as "arr" as mentioned earlier, the function call on this line would be written as arr.push(parsed [elem])
The next line is after the closing bracket of the for loop. It is an optional line that inserts an integer value to the front of our array, which tells us the number of items contained in the array. This is useful as a utility, so that you do not need to count the number of input items available for output.
The last line of code located before the closing bracket of the main() function is the return statement. It returns an array that creates an output in our Javascript actor for every top-level item from our input JSON string.
Please experiment with these scripts. Try grouping a number of sets of data and passing the JSON created into another Javascript actor to group these again into a single set. Then add multiple levels of ungrouping scripts to see the original values once again.
The image above illustrates the first step in packing multiple sets of data together.