Back to Blog
2025-12-26 6 min read

Mastering FileMaker PSoS Callbacks

FileMaker developers have historically faced a binary choice when offloading tasks to the server. You could choose "Wait for completion," which forces the user to stare at a loading indicator while the server processes data. Alternatively, you could choose "Don't wait," creating a fire-and-forget scenario where the user retains control, but the system loses observability—neither the user nor the developer knows if the script succeeded or failed.

The introduction of Perform Script on Server with Callback eliminates this trade-off. It provides the architectural middle ground: asynchronous processing with a guaranteed feedback loop.

Here is the architectural pattern for implementing callbacks to decouple your user interface from business logic.

The Architecture of the Callback

The callback pattern is a standard in modern software development. A process initiates a request and provides a specific function to execute only once the data returns.

In FileMaker, this architecture requires three distinct components:

  1. The Trigger Script: Initiates the process on the client side.
  2. The Server Script: Performs the heavy lifting, such as batch updates or API calls.
  3. The Callback Script: Executes on the client after the server completes to handle the result.

The Observability Gap

The traditional fire-and-forget method functions as a black hole. If a server script encounters a record lock or an API timeout, the user continues working, unaware that the operation failed. The callback pattern closes this loop. It allows the server to pass error states, success messages, or JSON payloads back to the specific client user who initiated the request.

Implementation Guide

To demonstrate this pattern, we will construct a month-end close routine. This process typically blocks the user interface for several minutes. We will refactor it to run asynchronously.

1. The Server Script (The Worker)

This script performs the logic. Crucially, it must return a result using the Exit Script step.

Script Name: Server_ProcessMonthEnd

# 1. Parse Parameters
Set Variable [ $json ; Value: Get ( ScriptParameter ) ]
Set Variable [ $month ; Value: JSONGetElement ( $json ; "month" ) ]

# 2. Perform Heavy Logic
Perform Script [ "Sub_CalculateMetrics" ]
If [ Get ( LastError ) > 0 ]
    # Return Error State
    Exit Script [ Text Result: JSONSetElement ( "{}" ; 
        ["status" ; "error" ; JSONString] ; 
        ["message" ; "Calculation failed." ; JSONString]
    ) ]
End If

# 3. Return Success State
Exit Script [ Text Result: JSONSetElement ( "{}" ; 
    ["status" ; "success" ; JSONString] ; 
    ["records_processed" ; $count ; JSONNumber]
) ]

2. The Callback Script (The Messenger)

This script executes on the user's machine. It receives the result from the server script via Get(ScriptParameter).

Script Name: Callback_MonthEndResult

# 1. Capture the Result from the Server
Set Variable [ $serverResult ; Value: Get ( ScriptParameter ) ]
Set Variable [ $status ; Value: JSONGetElement ( $serverResult ; "status" ) ]

# 2. Handle Outcomes
If [ $status = "error" ]
    Show Custom Dialog [ "Process Failed" ; JSONGetElement ( $serverResult ; "message" ) ]
Else
    Show Custom Dialog [ "Complete" ; 
        "Month closed. Processed " & JSONGetElement ( $serverResult ; "records_processed" ) & " records." 
    ]
    # Refresh the UI to show new data
    Refresh Window [ Flush cached join results ]
End If

3. The Trigger (The Initiation)

This script wires the components together. Note that we do not wait for completion; the callback handles the timing.

Script Name: UI_StartMonthEnd

# 1. Prepare Parameters
Set Variable [ $param ; Value: JSONSetElement ( "{}" ; "month" ; "12/2025" ; JSONString ) ]

# 2. Call PSoS with Callback
# The 'State' option determines if the callback pauses, resumes, or exits a currently running script.
Perform Script on Server with Callback [ 
    Specified Script: "Server_ProcessMonthEnd" ; 
    Parameter: $param ; 
    Callback Script: "Callback_MonthEndResult" ;
    State: Resume
]

# 3. Immediate User Feedback
Show Custom Dialog [ "Processing" ; "The month close has started in the background. You can continue working." ]

Architectural Nuances

While powerful, this pattern introduces specific context challenges that you must manage.

Context Persistence

The callback script attempts to execute in the window that initiated the call. As noted in the Claris documentation, if the user closes the window or the file before the server finishes, the callback is discarded.

  • Recommendation: Ensure your server script uses a transactional approach (commit all or commit none). This ensures data integrity is maintained even if the user closes their laptop and misses the success notification.

Layout Context

When the callback script fires, it inherits the user's current layout context, which may differ from the context at the moment of initiation.

  • Risk: If the callback attempts to modify fields (Set Field) while the user has navigated to a different layout, you may trigger "Field is missing" errors.
  • Recommendation: Always start your callback script by explicitly navigating to the required layout, or restrict the script to context-independent steps like Global Variables or Dialogs.

Queue Management

Users may click a button multiple times if they do not see immediate feedback. This spawns multiple server threads and results in multiple callbacks queuing up.

  • Recommendation: Disable the UI trigger button immediately after the first click, and re-enable it only within the callback script.

The Time to Refactor is Now

The "Freeze" is no longer an acceptable user experience. Users expect modern applications to remain responsive, regardless of the complexity of the data processing happening in the background.

Your Call to Action: Audit your solution today. Identify your three longest-running scripts that currently use "Wait for completion." Refactor just one of them this week using the Callback pattern. You will instantly modernize the feel of your application and eliminate the frustration of the "spinning blue wheel" for your users.

Further Reading

To implement this correctly, refer to the following resources for detailed parameter options and advanced integration patterns:

Mastering FileMaker PSoS Callbacks | Jeffrey Henry