Web Viewer Tips For FileMaker 19 – Hardening the FileMaker.PerformScript Function

If your web viewer code calls the FileMaker.PerformScript function when loading, it’s possible that it hasn’t been injected into the web viewer yet, and your code will fail with a breaking error. How can we harden our opening routine to ensure this breaking error doesn’t occur and provide the best experience for the user?

Part 3 of 3 of our series on Web Viewer Tips for FileMaker 19.

In a previous post on Web Viewer Tips we discussed how the new version of DayBack uses a familiar JavaScript and API pattern and the benefits of doing this. In this post, we’ll suggest bringing another common JS pattern into your app: try-catch.

FileMaker 19 Web Viewer Calendar
DayBack gets FileMaker data (Events and To-Dos) as part of its loading routine.

“Can’t Find Variable: FileMaker”

The web viewer will initiate making calls to the FileMaker file via the FileMaker.PerformScript function as the web viewer loads, but since FileMaker is also injecting the FileMaker.PerformScript function into the web viewer as it loads, it’s possible that the function hasn’t been injected before your code calls it. This is part of the asynchronous nature of JavaScript, sometimes the FileMaker.PerformScript function is there in time, and sometimes it isn’t. When it isn’t there, the error “Can’t find variable: FileMaker” is thrown. This is a breaking error, and your JavaScript will stop executing on the offending line.

In most situations, we can trap for this kind of error by testing for it in a simple If statement, something like:

If ( FileMaker && FileMaker.PerformScript ) {
   FileMaker.PerformScript ( 'some script' , 'some parameter');
 }

However, this does not help and you’ll still get the “Can’t find variable: FileMaker” error even when referenced in the if statement and the code breaks.

Using Try-Catch Blocks

Using Try-Catch blocks is a more robust way of trapping for errors and exceptions in JavaScript. All code run within the Try block will complete even if there is a potentially fatal error. Instead of the error being reported at the browser level, it will be sent to the Catch block as its argument. Here’s an example where the alert function is misspelled.

try {
   alret(‘Hello World’);
 }
 catch(e) {
   console.log(e.message);
 }

If the “alret” function is called outside of the try block, then this error would break our code and halt its execution at the line. By wrapping it in the try block, the code will continue safely and pass the message to the console log.

Since we know the FileMaker.PerformScript function will eventually be injected into the web viewer, we’re going to use the try-catch blocks to simply retry the routine a few times so that the injection can catch up with our code. This is the function we came up with, and even though it’s only on web viewer load that we’re worried about the failure, for consistency’s sake, we use it for all our calls to the FileMaker file.

function fileMakerCall(payload, retry) {

  //payload argument contains the script name
  var script = payload.script;

  //initialize the retry argument if empty
  retry = retry ? retry : 0;

  //number of times to retry before reloading the page
  //we've only observed the need for one retry befor FileMaker.PerformScript is there
  var numRetries = 5;

  //stringify the JSON payload for fileMaker
  var payloadString = JSON.stringify(payload);

  //begin try-catch
  try{
    FileMaker.PerformScript(script,payloadString);
  }
  catch(e){
    //try has failed re-run on a half second timeout if it hasn't been attempted too many times
    //enable for testing and debugging
    //console.log(e);
    if(retry < numRetries){
      setTimeout(function(){
        fileMakerCall(payload,retry);
      },500);
    }
    else{
      //too many retries, reload the whole page
      //although we've never needed this
      location.reload();
    }
  }

}

As you can see, the function will try to call FileMaker.PerformScript again up to 5 times. We don’t want to get stuck in an infinite loop, so providing a maximum number of retries is certainly a best practice, although I’ve never seen more than 1 retry be required for the FileMaker.PerformScript to be there and for the try block run without passing the error to the catch block. At the worst, users may experience a half-second delay during the loading routine instead of simply failing and needing to manually reload the web viewer.

Conclusions

The asynchronous nature of JavaScript can create timing issues. Although this error may seem particular to FileMaker and its web viewer, similar issues have existed for web developers for years:  so have the solutions they’ve come up with to handle them. JavaScript may feel new to many of us in the FileMaker world, but we can take comfort that there’s a wealth of experience out there that we can adapt to our solutions. If you encounter similar JavaScript issues with your web viewer apps, even though the exact terminology may be different from what we’re now doing in FileMaker, someone has likely solved the issue. Some googling and searching through Stack Overflow will likely provide the solution.

Featured Posts

Follow Along

Stay up to date with the latest news & examples from SeedCode

7 Comments

  • Hello Jason,

    Thanks very much for this post, and the code! please note that there is small spelling error on line 25 that breaks the script and throws a console error: “ReferenceError: Can’t find variable: setTimeOut”.

    To fix it, just need to change “setTimeOut(function()” to “setTimeout(function()” in line 25.

    Best regards,

    Andrés

    • seedcode

      Thanks, Andrés! (changed)

    • Jason Young

      Thanks for sharing that Jan, that’s great to know!

  • Thanks for the knowledge Jason! I’ll be using the wrapper in my own stuff.

    • Jason Young

      That’s great to hear Matt, thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

Check out some of our other posts ...

Comments in FileMaker Calendar

Highlight Notes and Comments in Your Calendar

Inline Notes in DayBack Calendar The latest DayBack extension adds an icon to your events when there is a comment present that matches your criteria. You can

Closed Through the New Year

SeedCode is closed for our holiday break from December 19th through the end of the year. We’ll have folks available in case of emergencies and

COMPANY

FOLLOW ALONG

Stay up to date with the latest news & examples from SeedCode

© 2023 SeedCode, Inc.