Best way to create multiple JSON Elements?

Trying to create a JSON structure in FileMaker like this:

{
"Cars" : "[VW, GM, Other]",
"First_Name" : "Alan",
"Last_Name" : "Jones"
}
{
"Cars" : "[Ford, Lexus, BMW]",
"First_Name" : "John",
"Last_Name" : "Smith"
}

I've tried two approaches, but both just give me the last JSON element.

Approach 1: (two set variables -- second one overwrites the $$JSON variable - expected result with this approach)

Set Variable [ $$JSON ; Value: JSONSetElement ("{}" ; [ "First_Name" ; "John" ; 0] ; [ "Last_Name" ; "Smith" ; 0 ] ; [ "Cars" ; "[Ford, Lexus, BMW]" ;0] ) ]
Set Variable [ $$JSON ; Value: JSONSetElement ("{}" ; [ "First_Name" ; "Alan" ; 0] ; [ "Last_Name" ; "Jones" ; 0 ] ; [ "Cars" ; "[VW, GM, Other]" ;0] ) ]

Set Field [ Untitled::json ; JSONFormatElements ( $$JSON ) ]


Approach 2: - build in a single Set Variable

Set Variable [ $$JSON ; Value: JSONSetElement ("{}" ; [ "First_Name" ; "John" ; 0] ; [ "Last_Name" ; "Smith" ; 0 ] ; [ "Cars" ; "[Ford, Lexus, BMW]" ;0] ; [ "First_Name" ; "Alan" ; 1] ; [ "Last_Name" ; "Jones" ; 1 ] ; [ "Cars" ; "[VW, GM, Other]" ;1] ) ]

Set Field [ Untitled::json ; JSONFormatElements ( $$JSON ) ]

===

Result:
{
"Cars" : "[VW, GM, Other]",
"First_Name" : "Alan",
"Last_Name" : "Jones"
}

Suggestions?

Thanks,

Looks like you need to make each Cars, First_Name and Last_Name objects entries in an array, or define them with unique object names:

Uniques Names:

JSONSetElement ( "{}" 

; [ "customer1.Cars" ; "[VW,GM,Other]" ; JSONString ]
; [ "customer1.First_Name" ; "Alan" ; JSONString ]
; [ "customer1.Last_Name" ; "Jones" ; JSONString ]

; [ "customer2.Cars" ; "[Ford,Lexus,BMW]" ; JSONString ]
; [ "customer2.First_Name" ; "John" ; JSONString ]
; [ "customer2.Last_Name" ; "Smith" ; JSONString ]

)

to give:

{
	"customer1" : 
	{
		"Cars" : "[VW,GM,Other]",
		"First_Name" : "Alan",
		"Last_Name" : "Jones"
	},
	"customer2" : 
	{
		"Cars" : "[Ford,Lexus,BMW]",
		"First_Name" : "John",
		"Last_Name" : "Smith"
	}
}

But the better approach would likely be to set them up as array entries, meaning you don't have manually label each element:

Let ( 

[

customer_object_1 = 
JSONSetElement ( "{}" 

; [ "Cars" ; "[VW,GM,Other]" ; JSONString ]
; [ "First_Name" ; "Alan" ; JSONString ]
; [ "Last_Name" ; "Jones" ; JSONString ]
)


;customer_object_2 = 
JSONSetElement ( "{}" 
; [ "Cars" ; "[Ford,Lexus,BMW]" ; JSONString ]
; [ "First_Name" ; "John" ; JSONString ]
; [ "Last_Name" ; "Smith" ; JSONString ]
)

; customer_array = 

JSONSetElement ( "{}" 

;  [ "Customers.[0]." ; customer_object_1 ; JSONObject ]
;  [ "Customers.[1]." ; customer_object_2 ; JSONObject ]

)


]

;


JSONFormatElements ( customer_array )


//Close Let
)

To give:

{
	"Customers" : 
	[
		{
			"Cars" : "[VW,GM,Other]",
			"First_Name" : "Alan",
			"Last_Name" : "Jones"
		},
		{
			"Cars" : "[Ford,Lexus,BMW]",
			"First_Name" : "John",
			"Last_Name" : "Smith"
		}
	]
}

In the latter example, the customer objects would normally be built up using a looping script (like you tried originally), with each object then inserted into the next available array index...

2 Likes

My first question would be why do you need them separate like that? Obviously, it's not standard JSON.

That's typically how these things are built. You loop over each customer and construct the json for that customer, then before moving on to the next customer you add the customer json object to the array.

1 Like

Sorry, my initial posting was not totally accurate, but your reply helped me a lot anyway! :slight_smile:

My confusion trying to do JSON in FileMaker is what is hard coded and what, if anything, is object based. Being a Java guy, how FileMaker does JSON is very non-intuitive to me though the steps are mostly the same. I'm not saying FMP's JSON is bad or anything along those lines. Rather, FMP's JSON is very different than corresponding Java logic to create your corrected version of my example:

I really appreciated your reply. I saved your example in the data viewer!

Thanks very much.

1 Like

Yep, I mis-posted my example...

@JamesG below did an awesome job with his reply clarifying my posting.

1 Like

The last screenshot you posted shows the 'cars' element as an array, whereas your first post shows it as a string.
If you want an array you'll have to change the example to make it so, but you get the concept of the JsonSetElement() by now I'm sure.

1 Like

Right.

Since I hadn't used them much, I was just messing around with the JSON functions in FMP and wasn't consistent with my posting.

The FMP JSON functions, once you understand their syntax, seem very straightforward.

Thanks for your reply.

1 Like

Hello Wim,

I guess this is a bit of a silly question, but it's the only way to learn.
What are the principal application differences between a JSON Array and the JSON Element.

I have been using JSON Elements to pass variables and find it to be a quantum leap over simple variable passing. But I can't wrap my head around the use of arrays.

TIA

Hello @BoloMan28,

Wim Decorte is no longer with The Soup… so don't expect an answer from him here any time soon.

A JSON element is a key-value pair. Order in the JSON result is not important. A JSON array is a list of identically-typed values. Creation order is preserved.

When would you use an array? Imagine you want to record a series of coordinates to define a shape. An array becomes a very useful construct in this case, where the first entry represents the first coordinate, the second entry represents the next coordinate… and so on. Adding a key and value type to each coordinate would become overly complex. How would you determine the key name for an undefined number of keys?

2 Likes

Hi David,

Thanks for the update, my understanding is as you described. Creating an Element seems to be quite easy; I have a few custom functions that can assemble elements in just a few lines of code. However, Arrays seem to be much more involved to create. I realize that a few of the custom functions I use for Elements can apply to arrays as well. But I really love the certainty offered by the named pairs.

That said, the Array does seem better when moving large pieces of code where the sequence can be accommodated when being parsed out or is not of relevance, using the assembly order as is.
Thanks again for taking the time.

1 Like

@bdbd I'm not sure if this is part of the JSON specification, unless you meant something else.

An array is an ordered collection of values. An array begins with [left bracket and ends with ]right bracket. Values are separated by ,comma.
A value can be a string in double quotes, or a number , or true or false or null, or an object or an array . These structures can be nested.

source: JSON

3 Likes

+1

I think @bdbd's explanation of the difference between Objects and Arrays excellent, but that same detail caught my eye. I don't believe it is a requirement for the entries of a JSON array to be of like type, though I recognize that many times in practice, such will be the case.

2 Likes

Some languages do require arrays to contain only a single type. JavaScript and JSON allow the array to contain a mixture of types.

I think the term for a collection of ordered unnamed elements of potentially mixed types, is 'tuple'. So when people ask about your arrays-as-params technique, I recommend repeatedly saying "pseudo-tuple" in a pretentious voice, and maybe also suggest that you only resorted to pseudo-tuples because FM doesn't support protobufs.

3 Likes

Yep, Java, Python, and C# all allow multiple types in arrays. I just tested with a string, Boolean, integer, and double values.

1 Like

@Bobino,

Thanks for catching that one. There is no need for types to be identical in FileMaker. As @steve_ssh pointed out, they are typically of the same type. As @jwilling pointed out, some languages make this a requirement of arrays. Not so with JSON… though it is not a language per se.

1 Like

Hi @OliverBarrett

When you tested this with Java, did you define the array to have a data type of Object? That is the only way I can think of where you'd be able to store multiple data types in a Java array. Otherwise, my experience is that they are strongly typed.

3 Likes

Hey Steve,

Here's the (hard-coded) test example, which uses "org.json.simple" library.

Let me know your thoughts.

org.json.simple.JSONObject first = new org.json.simple.JSONObject();
       first.put("first.name", "Alan");
       first.put("last.name", "Jones");
       first.put("owner", true);
       first.put("years.old", 30);
       **JSONArray cars = new JSONArray();**
       cars.add(0, "VW");
       cars.add(1, "GM");
       cars.add(2, "Lexus");
       cars.add(3, true);
       cars.add(4, 42);
       cars.add(5, 2.71);

       first.put("cars", cars);
       finalJson.add(first);

       // add second item...

       org.json.simple.JSONObject second = new org.json.simple.JSONObject();
       second.put("first.name", "Fred");
       second.put("last.name", "Smith");
       second.put("owner", false);
       second.put("years.old", 25);
       **JSONArray cars2 = new JSONArray();**
       cars2.add(0, "Tesla");
       cars2.add(1, "Toyota");
       cars2.add(2, "Chevy");
       cars2.add(3, false);
       cars2.add(4, 500);
       cars2.add(5, 3.14);

       second.put("cars", cars2);
       finalJson.add(second);

.
.
.

Finally, prints:

[
  {
    "owner": true,
    "years.old": 30,
    "cars": [
      "VW",
      "GM",
      "Lexus",
      true,
      42,
      2.71
    ],
    "last.name": "Jones",
    "first.name": "Alan"
  },
  {
    "owner": false,
    "years.old": 25,
    "cars": [
      "Tesla",
      "Toyota",
      "Chevy",
      false,
      500,
      3.14
    ],
    "last.name": "Smith",
    "first.name": "Fred"
  }
]
1 Like

Ah! Thanks Oliver! This makes sense, and I see the disconnect I was having.

Indeed, multiple types are being stored within an array structure, and the language is clearly Java, but the array is not the array implementation provided by the Java language -- it is from the org.json.simple library. That was what I did not figure out from earlier context. Thanks so much for clarifying it for me.

As an added personal bonus: It has been a long time since I have looked at any Java code, and it used to be such a fond part of my life -- makes me nostalgic!

3 Likes

Cool. Yes, the JSON library abstracts the data type issues so its "array" is not a Java array like you said also.

In Java, you could use an ArrayList() to also store any kind of object in an "array" type structure. An ArrayList is "like" an array, but has all the nice methods already implemented.

Typically, though (don't know how long it's been since you've been away from Java), you don't want multiple types in an ArrayList as that would be a super pain to interate over. Instead, you would use a construct (using Generics) that enforces a single Type (could be complex type like "Employee" or any type with any nested complexity) for the entire ArrayList.

Example:

List<Employee> emp = new ArrayList<>();
(you can only store Employee objects in this list - enforced).

The above instantiation also uses polymorphism to use the parent List Interface.
(Axiom obeyed: "Program to Interface, not to implementation", Gang-of-Four (aka, GoF) Design Patterns Book)

--

Thanks very much for your question and for your follow up!

Oliver

1 Like