@beezwax/fmbond

1.3.1 • Public • Published

FMBond

Table of Contents


Introduction

FMBondJS is part of the FMBond toolset. It manages interactions between FileMaker scripts and FileMaker web viewers.

Features

  • Get FileMaker script results as JavaScript Promises.
  • Perform JavaScript functions from FileMaker and return the results to FileMaker as part of the regular script flow.
  • Safely wait for the availability of the FileMaker injected class before attempting to perform scripts.
  • Extend through a built-in plugin registration system.

FMBondJS is also used as the function runner for the FMBondServer web service

Installation

  1. Install FMBondJS
npm i @beezwax/fmbond
  1. Download the following FileMaker file, and copy the FMBondRelay script into the target FileMaker file.
curl -O https://github.com/beezwax/fmbond-relay-script/raw/main/fmbond-relay-script.fmp12

Requirements

  • FileMaker 19.3 or higher.
  • All FileMaker web viewer objects used with FMBondJS must be named in the FileMaker layout inspector.
  • The option 'Allow JavaScript to perform FileMaker scripts' must be checked in all web viewers used with FMBondJS.

Usage

Performing FileMaker Scripts from JavaScript

FMBond.PerformScript(scriptName, scriptParameter [, options])

FMBond.PerformScript("add two numbers", { firstNum: 1, secondNum: 2 })
    .then((result) => console.log(result));

FMBond.PerformScript("Get User Data", "user-123", { timeout: 3000 })
    .then((data) => console.log(data.firstName))
    .catch((e) => console.log('request took too long', e));

The options object is optional and can contain any of the following (defaults shown):

{
    webViewerName: "",         // The name of the web viewer hosting the web code.
    timeout: null,             // Number of milliseconds to wait before a promise is rejected.
    callType: 0                // The FileMaker 'call type'.
    relayScript: "FMBondRelay" // The relay script as it is named in the FileMaker solution.
    ignoreResult: false        // When true, promise resolves immediately - does not wait for FileMaker script.
}

The callType can be any of the following values (when not provided it is "continue" by default). See the Claris documentation for more details

"continue"  (or 0, "0")
"halt"      (or 1, "1")
"exit"      (or 2, "2")
"resume"    (or 3, "3")
"pause"     (or 4, "4")
"interrupt" (or 5, "5")

The callType can alternatively be provided as the third parameter to PerformScript.

    FMBond.PerformScript("Get Data", "", { callType: "interrupt" });
    // is equal to
    FMBond.PerformScript("Get Data", "", "interrupt" );

FMBond.SetWebViewerName(webViewerName) | FMBond.GetWebViewerName()

The Web Viewer name can be globally adjusted. The provided FMBondRelay script does not require this, however when using a custom relay script usng the spec, the web viewer name may need to set in JS code.

    FMBond.GetWebViewerName(); // "" (default)
    FMBond.SetWebViewerName("myWebViewer");
    FMBond.GetWebViewerName(); // "myWebViewer"

FMBond.SetRelayScriptName(relayScriptName) | FMBond.GetRelayScriptName()

The Relay Script name can be globally adjusted. This is required if the default name (FMBondRelay) is not used.

FMBond.GetRelayScriptName(); // "FMBondRelay" (default)
FMBond.SetRelayScriptName("My Relay Script");
FMBond.GetRelayScriptName(); // "My Relay Script"

FMBond.SetWebViewerNameFromFM()

Determines the name of the web viewer that FMBond is running in and stores it. This is useful for ensuring that subsequent FMBond.PerformScript calls do not invoke potentially expensive searches for the initiating web viewer.

Returns a promise

FMBond.GetWebViewerName(); // ""
FMBond.SetWebViewerNameFromFM()
    .then((result) => {
        console.log(result) // "myWV"
        console.log(FMBond.GetWebViewerName()) // "myWV"
    });

FMBond.SyncConfig()

By defining a JSON blob in the Web Address portion of the Web Viewer:

  • SyncConfig returns the Web Viewer JSON configuration as a promise result.
  • SetWebViewerConfigFromFM calls FileMaker and updates the configuration stored in FMBond.
  • SetWebViewerConfig(webViewerConfig) allows manual overwrite of the configuration stored in FMBond.
  • GetConfig returns the current configuration stored in FMBond.
// For example:
// • A Web Viewer is in the context of the PERSON table.
// • The PERSON::NAME field is "John Smith".
// • This Web Viewer's Web Address is set to JSONSetElement( "{}" ; "NAME" ; PERSON::NAME ; JSONString )

FMBond.GetConfig() // "{}"
FMBond.SetConfig({"NAME": "Kevin Paddlesmith"});
FMBond.GetConfig() // { "NAME": "Kevin Paddlesmith" }
FMBond.SyncConfig().then((config) => {
    console.log(config.NAME) // "John Smith"
});

FMBond.RegisterScript(pluginOptions)

It possible to extend FMBond by registering custom FileMaker scripts, which can then be can be called as methods. This allows the FMBondRelay script to be bypassed and may make it easier to implement custom behavior.

  1. Create a script in FileMaker.
  2. Perform FMBond.RegisterScript giving it the appropriate pluginOptions.

pluginOptions

  • exec: the method that becomes available to use on the FMBond class.
  • scriptName: the FileMaker script that will be run when the method defined in exec is called.
  • throwIf: (optional) callback function that takes the result of the script defined in scriptName as a parameter. If the function returns true an error will be thrown.
// define the script
FMBond.RegisterScript({
    exec: "executeDataApi",
    scriptName: "Execute Data Api",
    throwIf: (scriptResult) => {
        return scriptResult.messages[0].code !== "0" ;
    },
});


// Performing the script
const myQuery = {
    layouts: "FAKE_DATA",
    query: [{
        SOME_DATA: "==definitely data here",
    }],
};
FMBond.executeDataApi(myQuery)
    .then((result) => {
        console.log('my data', result);
    })
    .catch((e) => {
        console.log('query failed', e.toString());
    });


// The second parameter can also take advantage of FMBond options
FMBond.executeDataApi(myQuery, { timeout: 3000, callType: "interrupt" })
    .then((result) => {
        console.log('my data', result);
    })
    .catch((e) => {
        console.log('query failed', e.toString());
    });

Promise rejection and Error Handling

The promises settled by the FMBondRelay script will only reject when the specified FileMaker script is missing.

Otherwise, the result of the script's Exit Script[] step will be returned as the result of resolved promise and not a rejected promise. Because there is no standard way to indicate that a FileMaker script resulted in an error, the result of the promise will need to be inspected and an error thrown if required.

Note that when registering a plugin, the throwIf parameter can be used set the result state(s) that should throw errors.


Performing JavaScript functions from FileMaker

A web viewer that contains the FMBond class can return the result of a JavaScript function performed by FileMaker's Perform Javascript in Web Viewer script step. This allows the following FileMaker scripting pattern:

Perform JavaScript in Web Viewer [ ... ]
Set Variable[ $javaScriptResult; Get ( ScriptResult ) ]

That is, results of functions called using Perform Javascript in Web Viewer can be captured inline with minimal impact on the normal FileMaker script flow.

To utilize this feature configure the Perform Javascript in Web Viewer script step as follows:

  • Function Name: FMBond
  • First parameter either
    • a function in the global (window) JavaScript context of the web viewer OR
    • a JavaScript function (arrow or classic) defined as a string
  • Subsequent parameters will be passed into the function. To treat a JavaScript parameter as a callback function, prefix it with the 'ƒ' symbol (⌥ + f on macs).

Results are always obtained via Get ( ScriptResult ), nested in the response.result key. The response.result prop will be appropriately formatted (eg: as a number for numbers, string for strings, object for objects, etc...).

Example 1 Calling a function AddTwoNumbers that is accessible via window.AddTwoNumbers in the web viewer.

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: "AddTwoNumbers", 3, 5 
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 8

Example 2 Calling a FileMaker-defined function (define and run JavaScript on the fly in FileMaker)

Set Variable [
    $_add_two_numbers_func ;
    Value: "(a, b) => a + b"
]

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: $_add_two_numbers_func, 3, 5
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 8

Example 3 Support for Callbacks (remember to prefix with an 'ƒ')

Set Variable [
    $_add_number_with_callback ;
    Value: "function (myCallbackForC, a, b, c) { return a + b + myCallbackForC(c); }"
]

Set Variable [
    $_times_two ;
    Value: "ƒ(value) => value * 2"
]

Perform JavaScript in Web Viewer [
    Object Name: "MyWebViewer" ;
    Function Name: "FMBond" ;
    Parameters: $_add_two_numbers_func, $_times_two, 3, 5, 50
]

Set Variable [
    $_new_number ;
    Value: JSONGetElement ( Get ( ScriptResult ) ; "response.result" )
]
// $_new_number = 108

Get ( ScriptResult ) response

{
	"messages" :
	[
		{
			"code" : "0",
			"message" : "OK"
		}
	],
	"response" :
	{
		"result" : 108
	}
}

Errors are captured and returned for the following scenarios:

  • function does not exist in JavaScript.
  • function defined in FileMaker has invalid syntax (for example, a missing parenthesis: "(a, b => a + b").
  • function executed in JavaScript throws an error.
  • FMBond does not exist in the web viewer (in this case, the PerformJavascript step itself will surface an error).
{
	"messages" :
	[
		{
			"code" : "5",
			"message" : "The function 'MyGlobalFunc' is missing from the global scope, or is not a valid function definition"
		}
	],
	"response" : {}
}

Contributors

Brendan Pierce, Alec Gregory, Brandon Montoya, Max Petrusenko, and valuable contributions from members of the Beezwax team

Package Sidebar

Install

npm i @beezwax/fmbond

Weekly Downloads

3

Version

1.3.1

License

MIT

Unpacked Size

228 kB

Total Files

8

Last publish

Collaborators

  • gosukiwi
  • alecgregory
  • brenda_p
  • beezwax-systems