0

I can pass a record as a function argument!

OMG, I just tried this and it worked! Did anybody else already know about this? I can't find any reference to this capability to pass a record into a function.

function test(node : Entries) do
    node.Headline
end;
alert("Result='" + test(this) + "'")

The alert was:

Result='Cripple Creek lot'

which is the Headline of the Entries record ('this') that was open when the script was executed.

2 replies

null
    • Sean
    • 5 yrs ago
    • Reported - view

    mkay... I don't think you can name records. So based on my own testing I'll assume you meant table instead of record. Scope is an issue... Since it doesn't work in the console, it probably won't work in 'Global script definitions'. I had to define the function in a formula field in the table I was testing this on. I wasn't able to select a specific record using the function even though I used the select command. Probably because I couldn't use 'node' in the select command, as you would expect to be able to do with a parameter. I did get the field information like you did, but it's always from the same record in the table.

    • Tim
    • 5 yrs ago
    • Reported - view

    OK, I've done some more testing, with mixed results. Here's what works and what doesn't, so far. This seems to be a capability that you can use very carefully, if your requirements match up with the behavior. I'm not sure how generally useful this is, at this time, but I wanted to get my results into the forum. I may also put this in an email to support, since some of this is obviously not behaving as they would probably like it to.

    The following function works under very specific circumstances, whether you define the function in a button script, a formula script, or in the global script. It behaves the same regardless of which table you're in when your script calls it.

    function test(rec : DataTable) do
        (rec = null) + "/" + rec.Text + "/"
    end

    The function expects a record of "type" 'DataTable' when you call it.

    The function returns a boolean indicating whether the incoming 'rec' argument is null, along with the value of the 'Text' field in 'DataTable' record that is passed in (empty if 'rec' is null, of course).

    You can pass the function a variable in which the result of a record() function call has been stored, as in:

    var tr := record(DataTable,3);
    let res := test(tr)

    In this case 'res' contains "No/c/", since the 3rd record of 'DataTable' happens to contain a "c" in its 'Text' field.

    Note that you cannot pass the record() call itself as the function argument, as in:

    let res := test(record(DataTable,3))

    If you do this in a formula script, then Ninox reports an error when you click 'Save Changes': "ReferenceError: Can't find variable: db" and then puts you back into the 'Edit Fields' dialog until you fix it.

    If you do this in a button script, then Ninox lets you save it but then hangs when you click the button and you'll have to kill Ninox.

    If you do this in the console, then Ninox just quietly doesn't do anything when you run it, but at least it doesn't hang.

    You cannot use the results of the first() or last() or item() functions with this function, the function reports that the argument is null. If you pass the first/last/item calls directly in the function call, you still a null argument, but at least it doesn't hang/error like putting record() in the function call does. All of these pass a null into the function:

    var tr := first(select DataTable);
    let res1 := test(tr);
    let res2 := test(last(select DataTable));
    let res3 := test(item(select DataTable,3))

    You also get a null argument if you try passing a loop variable to the function, as in:

    for t in (select DataTable) do
        test(t)
    end

    You do get a valid argument if you use the select result directly, as in:

    (select DataTable).test(this)

    Obviously, any field references within the function must be valid for the table identified as the argument type, or Ninox won't let you save the script.

    Interestingly, though, you can pass a record from any table to the function and it will pull the value from the field in the passed record that has the same internal field ID as the table in the argument definition. This works OK if the fields are the same type, but is empty if they are not, or if that internal field ID doesn't exist in the passed record (I haven't tested a lot of combinations).

Content aside

  • 5 yrs agoLast active
  • 2Replies
  • 2361Views