The Gearbox Blog

We write so you can learn from us and we can learn from you.

Sep 12 2018

TAGS filemaker

Passing Parameters with FileMaker + JSON - Still Evolving

by Michael Layne |

In the Beginning...

A long time ago, we didn't have the ability to pass values around like we do now. At least some of us remember those days...

I was among the masses that took Geoff Coffey's lead and started using custom functions to pass multiple parameters over a decade ago. As time passed, the next thing that stuck was the now legendary #Parameters set of functions -  a gift from Jeremy Bante several years ago.

With the advent of FileMaker 16, we got native JSON. As lovely as it was (and is), My brain felt a slight step backward as I lost a bit of control and efficiency as I decided to force myself to use JSON everywhere I could. I even presented on this topic in June at @dotmfp in Berlin.

Passing JSON back to a script without anything fancy means you need to declare your variables one at a time - which has been argued is a good thing - verbose, easy to follow, know what to expect. But after years of using a prototype for my FileMaker scripts like this below, I wanted to stick with doing it all at once.

getBidSheet ( id  {; card })

Sometimes if you procrastinate, you are rewarded

I started to tinker with a custom function but never completed it.  Then one cold day in January (I'm sure it was cold in Chicago at least), Mislav Kos of Soliant shared a shiny new custom function to parse JSON that was just what I was looking for (well, almost).

I didn't hesitate using this everywhere (and got to get rid of stuff like this:)

Set Variable [ $parameters ; Value: Get ( ScriptParameter ) ]
# now do this
Set Variable [ $id ; Value: JSONGetElement ( $parameters ; "id" ) ]
Set Variable [ $card ; Value: JSONGetElement ( $parameters ; "card" ) ]

Set Variable [ $! ; Value: JSONCreateVarsFromKeys ( Get ( ScriptParameter ) ; "" ) ]

What about setting multiple key-value pairs?

I came up with a script I've been using for years to set as many key-value pairs as I wanted using the #Parameters function.  Consider this script...

setFields ( field[] ; value[] {; flush ; object ; portal ; layout } )

and this to pass...

# ( "field[1]" ; GetFieldName ( SELECTOR::ID_RESPONSE ) ) & 
# ( "value[1]" ; responses::id ) &
# ( "field[2]" ; GetFieldName ( SELECTOR::ID_PATIENT ) ) & 
# ( "value[2]" ; respPatients::id )

the stuff that does the work...

# do we have multiple fields here?
If [ PatternCount ( Get ( ScriptParameter ) ; "[" ) ] 
    Set Variable [ $n ; Value: 0 ] 
    Loop
        Exit Loop If [ IsEmpty ( $field[$n + 1] ) ] 
        Set Variable [ $n ; Value: $n + 1 ] 
        Set Field By Name [ $field[$n] ; $value[$n] ] 
    End Loop
Else
    Set Field By Name [ $field ; $value ] 
End If
Commit Records/Requests [ Skip data entry validation ; With dialog: Off ] 

I can only speak for myself, but what I wanted now was something that allowed me to do what the above script does, but with using JSON.  It didn't take long if you have a bit of JSON structure knowledge. I finally settled on this.  I get to leverage JSON, leverage my go-to custom function for parsing JSON, and all is right with the world.

The script:

setFieldsJSON ( array ( field ; value {; object ; portal ; layout } )

The parameters:

JSONSetElement ( "{}";
 [ "pairs[0].field" ; GetFieldName ( FIND::id_VENDORS ) ; JSONString ] ;
 [ "pairs[0].value" ; FIND.companies::id ; JSONString ] ; 
 [ "pairs[1].field" ; GetFieldName ( FIND::id_PRODUCTS ) ; JSONString ] ;
 [ "pairs[1].value" ; FIND.companies::id ; JSONString ] ; 
 [ "object" ; "portal.vendors" ; JSONString ] 
)

The script bit that does the heavy lifting:

# do we have multiple fields here?
Set Variable [ $count ; Value: ValueCount ( JSONListKeys ( $pairs ; "" ) ) ] 
Set Variable [ $i ; Value: 0 ] 
Loop
    Set Variable [ $field ; Value: JSONGetElement ( $pairs ; "[" & $i & "].field" ) ] 
    Set Variable [ $value ; Value: JSONGetElement ( $pairs ; "[" & $i & "].value" ) ] 
    Set Field By Name [ $field ; $value ] 
    Set Variable [ $i ; Value: $i + 1 ] 
    Exit Loop If [ $i > ( $count - 1 ) ] 
End Loop
Commit Records/Requests [ Skip data entry validation ; With dialog: Off ]

We're done

This stuff helps our team be more efficient and this stuff is very portable.  We have this running in several projects right now and it's a breath of fresh air knowing we have this and so many wonderful tools from the FileMaker community at our disposal.

HTH.