diff --git a/agent/docs/knowledge/MANIFEST.md b/agent/docs/knowledge/MANIFEST.md index 098a08a0..b59ead08 100644 --- a/agent/docs/knowledge/MANIFEST.md +++ b/agent/docs/knowledge/MANIFEST.md @@ -20,7 +20,7 @@ All paths are relative to `agent/docs/knowledge/`. | `disambiguation.md` | Commonly confused FileMaker term pairs and non-negotiable structural invariants: table vs TO, stored vs auto-enter calc, commit record vs commit transaction, layout context vs script context, fmxmlsnippet vs SaXML, and key constraints on indexing, found sets, transactions, and security | disambiguation, confused terms, table occurrence, TO, stored calculation, auto-enter, commit, transaction, fmxmlsnippet, layout context, script context, custom function, Get function, List view, Table view, invariants, constraints, indexing, found set, PSOS, privilege set, security | | `variables.md` | FileMaker variable scoping and naming conventions: $ local, $$ global, ~ calculation-local, $$~ private global, stale global gotcha, when to use globals vs locals, performance, and Let() relationship | variable, scope, local variable, global variable, $$ global, ~ tilde, Let, camelCase, variable naming, stale global, session, script scope, calculation scope, private global | | `paste-dependency-order.md` | The correct installation order when pasting FileMaker objects into a solution: custom functions → tables → fields → value lists → scripts → layout objects → script steps → custom menus. Explains why relationships are excluded and how to diagnose broken references caused by out-of-order pasting. | paste order, dependency order, install order, custom function, table, field, value list, layout, script, custom menu, broken reference, fmxmlsnippet, clipboard, copy paste, installation sequence | -| `json-functions.md` | JSONGetElementType return constants (JSONString/Number/Object/Array/Boolean/Null = 1–6, 0 = not found), why JSONUndefined and JSONMissing do not exist, positive and negative key-existence patterns, root element type check | JSONGetElementType, JSONGetElement, JSONSetElement, JSON type, JSONUndefined, JSONMissing, JSONString, JSONNumber, JSONObject, JSONArray, JSONBoolean, JSONNull, key exists, missing key, JSON guard, JSON constant | +| `json-functions.md` | JSONGetElementType return constants (JSONString/Number/Object/Array/Boolean/Null = 1–6, 0 = not found), why JSONUndefined and JSONMissing do not exist, positive and negative key-existence patterns, root element type check. Array building: `[+]` appends a new element, `[:]` addresses the last element — use `[+]` for the first property of a new object and `[:]` for all remaining properties. Numeric index keys produce objects not arrays. | JSONGetElementType, JSONGetElement, JSONSetElement, JSON type, JSONUndefined, JSONMissing, JSONString, JSONNumber, JSONObject, JSONArray, JSONBoolean, JSONNull, key exists, missing key, JSON guard, JSON constant, array, append, [+], [:], array element, loop, accumulator | | `return-delimited-lists.md` | Searching return-delimited lists correctly: the boundary bug in naked Position() calls, the ¶-wrap fix, the `ValueExists()` custom function as the preferred solution, and related Value* custom functions (ValuePosition, ValueToggle, ValuesWalk, ValuesWrap, ValueExtract) | return-delimited list, ScriptNames, LayoutNames, FieldNames, TableNames, ValueListItems, List, Position, FilterValues, ValueExists, ValuePosition, ValueToggle, ValuesWalk, ValuesWrap, ValueExtract, boundary, first value, last value, list membership, list search | | `file-operations.md` | FileMaker file operation patterns: Delete File step (id 197) for new scripts; legacy Export Field Contents hack found in older scripts (omitting field target raises error 102 but clears the file); Show Custom Dialog InputFields structure for capturing user input | file delete, Delete File, delete file, remove file, Export Field Contents, Create Data File, error 102, field missing, overwrite, legacy, older script, Show Custom Dialog, InputFields, input field, user input, dialog, capture input, password character | | `script-ids.md` | FileMaker object IDs are file-specific: assigned from a per-file incrementing counter, change when copied between files, not portable or stable across solutions. Never hardcode IDs in documentation — reference by name, resolve from CONTEXT.json or index files | script ID, object ID, internal ID, file-specific, copy script, Perform Script, ID mismatch, different file, CONTEXT.json, portable, incrementing, monotonic | diff --git a/agent/docs/knowledge/json-functions.md b/agent/docs/knowledge/json-functions.md index fd4d45e4..23d18399 100644 --- a/agent/docs/knowledge/json-functions.md +++ b/agent/docs/knowledge/json-functions.md @@ -89,6 +89,47 @@ This is the pattern used in `AGFMScriptBridge` to validate that the parameter is --- +## Building JSON arrays with JSONSetElement + +FileMaker uses special key notation to append to and reference elements in JSON arrays: + +| Key | Meaning | +|-----|---------| +| `[+]` | Append a new element at the end of the array | +| `[:]` | Reference the last element in the array | + +**Use `[+]` for the first property of a new object, then `[:]` for all remaining properties on that same object:** + +``` +// Correct — [+] creates the new element, [:] addresses the same element +JSONSetElement ( $input ; + [ "[+].id" ; "10001" ; JSONNumber ] ; + [ "[:].name" ; "My Name" ; JSONString ] ; + [ "[:].category" ; "Cateory"" ; JSONString ] +) +``` + +**Do NOT use `[+]` for every property** — each `[+]` appends an entirely new element: + +``` +// Wrong — creates three separate array elements instead of one object +JSONSetElement ( $input ; + [ "[+].id" ; 10001 ; JSONNumber ] ; + [ "[+].name" ; "Name" ; JSONString ] ; + [ "[+].category" ; "Category"" ; JSONString ] +) +``` + +**Do NOT use numeric index keys** (`"0.id"`, `"1.id"`) — FileMaker treats these as object keys, not array indices, resulting in `{"0":{"id":...}}` instead of `[{"id":...}]`. When returned as `JSONArray` type, FileMaker collapses the object to `[]`. + +**Initialise** the accumulator variable as `"[]"` before the loop: + +``` +Set Variable [ $input ; "[]" ] +``` + +--- + ## References | Name | Type | Local doc | Claris help |