1 2 3 Previous Next 36 Replies Latest reply on May 19, 2017 4:45 PM by beverly

    FM16 JSON as script parameter

    JaredHague

      So I have always used the "List" function when passing multiple parameters.  It has served me well over the years and only occasionally been a problem.  An example being when a parameter is empty the ones after shift one index back. Typically I have a check or pass a dummy value for empty.

      I am pumped to be passing JSON!!  I could have been doing this before with some custom functions but now there is a native solution its quite exciting. Also the ability to have much more complex parameters is really nice. 

      Anyway just wondering about all your thoughts on this.

        • 1. Re: FM16 JSON as script parameter
          jbrown

          We at Soliant Consulting have a blog post about that, to be published in a day or so. I imagine others will be posting about the same thing.

          It is exciting; being able to pass the key (variable name) and value into a script. Seems there will need to be a CF that parses it, or you can parse it 'manually' inside the script for use. Or, there may not even need to be a need to set the individual values into individual variables.

          • 2. Re: FM16 JSON as script parameter
            jbante

            There have been many alternative formats that accomplished the same thing for intra-FileMaker communication for years, but JSON is bound to be the de facto standard way to do it now. This will be great for the interoperability of shared code. It will be great to be using the same format for internal and external communication. Just for intra-FileMaker communication, the interoperability that comes from being built-in is the only advantage relative to the existing alternatives, but that's enough to be worthwhile.

            1 of 1 people found this helpful
            • 3. Re: FM16 JSON as script parameter
              Ronnie

              Hi Jared,

              You're not alone, it's a thought many are having. There are already a few examples posted here: https://community.filemaker.com/community/discussions/app-innovations/content

              1 of 1 people found this helpful
              • 4. Re: FM16 JSON as script parameter
                smith7180

                jbante-

                 

                While I look forward to using JSON for passing parameters, I'd just like to publicly thank you for your custom parameter functions.  They've been a joy to work with for many years now.

                • 5. Re: FM16 JSON as script parameter
                  jrenfrew

                  agreed Jeremy

                   

                  Couple of things that would be helpful ( so I can get rid of my new shiny CF) is a native way to convert 1 level deep JSON to variables based on the key names

                  and an array count function

                  • 6. Re: FM16 JSON as script parameter
                    RobWestergaard

                    I've started to pass script parameters using this format:

                    JSONSetElement ( "{}" ;

                        [ "parameter1" ; "some_value" ; JSONString ] ;

                        [ "parameter2" ; "some_other_value" ; JSONString ] ;

                        ...

                    )

                    In the script, I have a single "Set Variable" script step at the beginning to set a dummy variable to the following:

                    InstantiateJSONParameters ( Get ( ScriptParameter ) )

                    ...and this is the custom function I'm using to set all the script parameters at once:

                    InstantiateJSONParameters ( json ) =

                     

                    If ( not IsEmpty ( json ) and ValueCount ( JSONListKeys ( json ; "" ) ) ; Let (

                         [

                              firstKey = GetValue ( JSONListKeys ( json ; "" ) ; 1 ) ;

                              firstKeyValue = JSONGetElement ( json ; firstKey ) ;

                              expression = "Let ( $" & firstKey & " = " & Quote ( firstKeyValue ) & " ; \"\" )"

                         ] ;

                     

                         Evaluate ( expression ) & InstantiateJSONParameters ( JSONDeleteElement ( json ; firstKey ) )

                     

                    ) )

                    This function will not type the varaibles, so they will all be text unless you re-set them later using GetAsNumber() et.al. However, it's a quick way to set all of the passed variables without explicitly needing to know the names.

                     

                    I haven't tested this exhaustively, so I'm sure I will find problems that need to be ironed out, but it's a starting point.

                    • 7. Re: FM16 JSON as script parameter
                      jbante

                      I've done this kind of thing using the #Assign function in the past. I'm leaning in the opposite direction now, for several reasons:

                      • Power to decide what variables get set and what variables don't should rest solely with the script receiving a parameter (or result). Setting variables based on the contents of the parameter gives the source of that parameter the ability to decide what variables to set. Not setting extra variables is convenient for a series of scripts that might receive the same parameter containing values not relevant to every script. This is crucial for scripts receiving results that need to avoid naming collisions between the parent script and the result from the child script.
                      • Having a block of Set Variable script steps at the beginning of a script is a beautiful thing. With this pattern, the data that a script expects in the parameter and the executable logic for extracting that data can be the exact same thing. Some additional commenting on the requirements for each value can be included as comments in the Set Variable step. This substantially reduces the need to have separate header comment documentation describing the same information.
                      • I'm increasingly disillusioned with the #Assign function because it hides details from me when they should not be hidden. Encapsulation is important for wrapping up chunks of logic so I don't have to think about how it works anymore so I can focus my puny human attention on other things. Encapsulation (and encapsulation-like hiding) is best restricted to details we can safely forget, details we're not responsible for anymore. When I'm writing a script, the parameters to the script are not something that should be obscured from me within that script. When I'm working on that script, that's something I'm responsible for. There should be a flashing neon sign saying, "This is important! I don't care how many times you've seen it already; look at it again!"
                      • If a block of Set Variable steps parsing out parameters ever becomes burdensome to look at, that's probably a useful cue that the script needs to be refactored in some dramatic way. Masking the symptom is not a cure. Putting the same logic into fewer script steps doesn't make a script easier to understand. Putting less logic in a script makes it easier to understand.
                      9 of 9 people found this helpful
                      • 8. Re: FM16 JSON as script parameter
                        Paul Jansen

                        jrenfrew wrote:

                         

                        agreed Jeremy

                         

                        Couple of things that would be helpful ( so I can get rid of my new shiny CF) is a native way to convert 1 level deep JSON to variables based on the key names

                        and an array count function

                        Would you care to share the "new shiny CF"....

                        • 9. Re: FM16 JSON as script parameter
                          beverly

                          LOL! I was just going to ask where was the new blog from Jeremy on this.

                          beverly

                          • 10. Re: FM16 JSON as script parameter
                            jrenfrew

                            Paul...

                            #_assignJSON ( JSONDeleteElement ( param ; _key ) )

                             

                             

                             

                            Case (

                              IsEmpty ( param ) ; "" ;

                              Left ( JSONGetElement ( param ; "" ) ; 1 ) = "?" ; False ;

                              //else

                             

                             

                            Let ( [

                              _keyList = JSONListKeys ( param ; "" ) ;

                              _key = GetValue ( _keyList ; 1 ) ;

                              _value = JSONGetElement ( param ; _key ) ;

                              _valueIsNumeric = Exact ( _value ; Filter ( _value ; "0123456789-.," ) ) and not Left ( _value ; 1 ) = "0" ;

                              _quoteMark = If ( _valueIsNumeric ; "" ; "\"" ) ;

                              _evaluateString = "Let ( $" & _key & " = " & _quoteMark & _value & _quoteMark & " ; True ) " ;

                              _isValid = IsValidExpression ( _evaluateString ) ;

                              $json.error = If ( _isValid ; Let ( ~ = Evaluate ( _evaluateString ) ; "" ) ; "error setting key: " & _key )

                             

                             

                            ] ;

                             

                             

                              Case (

                              ValueCount ( _keyList ) = 1 ;

                              _isValid ;

                              #_assignJSON ( JSONDeleteElement ( param ; _key ) )

                             

                              ) //end case

                             

                             

                            ) //end let

                             

                             

                            ) //end case

                            • 11. Re: FM16 JSON as script parameter
                              Todd Geist

                              Jeremy is spot on

                              1 of 1 people found this helpful
                              • 12. Re: FM16 JSON as script parameter
                                Paul Jansen

                                I too have been using #assign for some time and I love the fact that all the parameters can be set in a single script step.  However, you make a strong argument for explicit setting of each variable with the added benefit of this being self documenting as to which variables are required.

                                 

                                So I thought about how the get the best of both worlds and came up with this, (although I'm sure it can be improved)

                                 

                                Set Variable[ $error ;

                                Let([

                                $param = get(scriptparameter)

                                $id = JSONGetElement ( $param ; "id" ) ;

                                $name = JSONGetElement ( $param ; "name" ) ;

                                $price = getasnumber( JSONGetElement ( $param ; "price" ) ) ;

                                $stock = JSONGetElement ( $param ; "stock" ) //optional

                                ];

                                True

                                )]

                                 

                                I suspect there will be many approaches to using JSON for script parameters and I look forward to seeing what the FileMaker experts come up with.

                                • 13. Re: FM16 JSON as script parameter
                                  jbante

                                  Most of my last reply to you was largely copied from another discussion where I was arguing against exactly this idea to set all the parameters with a single Let function, rather than #Assign. With Set Variable [ $ignoreMe ; Let ( [ ... ] ; "" ) ], at least the receiving script is in control of what variables get set by what parameter. All of the other problems with #Assign are still there. Putting all the parameter (or result) logic into a single step does not make a script easier to read. If anything, it makes understanding a script harder, since developers have to open the step to see what's happening, rather than just scanning the series of steps with calculations short enough to be read without opening them.

                                  • 14. Re: FM16 JSON as script parameter
                                    KenNewell

                                    So many ways to do the same things and we all become familiar with a way and stick to it.  For me I have 3 CFs that I have created for NamedPair, ParseScriptParameter, ParseScriptResult.  The idea is to pass a list of named pairs and simply extract them.  I like this method because I am not required to list them in a specific order.  Plus when I read my code I see the value that I am passing and what the "name" of the value is.  I have found these very helpful but that is my 2 cents worth.  Maybe one of these days will write it up to share.

                                    1 2 3 Previous Next