calling funcions in an external JS file from within the file

Workarounds and usability notes.

calling funcions in an external JS file from within the file

Postby John Robin Dove » Mon Aug 28, 2017 3:08 pm

Re my last post in 'transparency etc', I don't think XML files are causing this.

I've almost found a workaround but I'm too tired to carry on tonight.

The problem has something to do with how variables are sent from the JS file to the main application. showRequest uses pgTBObjSet + user to send a string in the value parameter to a field in the main app that gets the required translation and then uses showRequest2 to display the dialog box. value contains the contents of 4 text variables separated by the "§" character. These come from the parameters of the showRequest function function tbfunction_showRequest(txt, button1, button2, objName) The problem is that button2, and objName are often null. This is not a problem if showRequest is called from the main app. The field that gets the translation receives, for example, "The media player will start again. Press on a Ctrl key to add another action.§OK§§". However if showRequest is called from within the JS file it receives "The media player will start again. Press on a Ctrl key to add another action.§OK§undefined§undefined". This seems to prevent it working and no dialog box appears.

I think I''ll probably find a fix but I'd like to know why this error has only appeared recently. It had worked perfectly for years until now. I hope there are no more new unexpected errors like this but I have a feeling there may well be a few more. The system seems to have got far fussier than it used to be for some reason.
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am

Re: calling funcions in an external JS file from within the

Postby Clifton » Mon Aug 28, 2017 4:51 pm

Consider your code as represented this way:
  var txt = "textA", button1 = "textB", button2, objName;
showRequest( txt, button1, button2, objName );

In the Actions Editor:
The ToolBook actions system automatically assigns empty strings "" to any variable that is undefined. This is contrary to how JavaScript works, but causes everything to work in a predictable way for ToolBook developers at the Actions level. Therefore, showRequest() will receive your variables from the Actions system this way:
  • txt = "textA"
  • button1 = "textB"
  • button2 = ""
  • objName = ""
In JavaScript:
tbfunction_showRequest( txt, button1, button2, objName ) will send the variables EXACTLY as they are typecast or defined . . . so they are sent this way:
  • txt = "textA"
  • button1 = "textB"
  • button2 = null (at javascript level) or "undefined" (Actions system interpreted)
  • objName = null or "undefined" (see above)

This is not a PowerPac issue and never has been. Rather it is a logistic issue between the way each interface is typecasting the variables. The key on your end to make sure everything is typecast in a predictable way regardless of whether the variables are sent from the Actions system or from JavaScript.

SOLUTION:
Adjust your function showRequest2() to make things predictable.
Like this:
function showRequest2( [yourParams] ) {
var txt, button1, button2, objName;
.... do some stuff ....
//Now send the vars to the Actions interface so any undefined var has a default string type value
tbfunction_showRequest( txt || "", button1 || "", button2 || "", objName || "" );
}


In a way, you are right in that this is a lot like the bug problem with snapObjectToCenter() where the align parameter was received as null from your function call to from JavaScript directly to the PowerPac without using the Actions system. My fix was simply to make sure the align parameter was converted to a predictable default if null or undefined is sent from a native JavaScript call or XML file. This way the function will succeed every time.

BTW: You do not have to expressly send a catenated string separated by "§". Things can get clunkly and overly complicated. Try this instead from your JavaScript function:
tbfunction_pgTBObjSet( [tbName], "user", [ txt, button1, button2 || "", objName || "" ] );

Notice, I've defined an array to hold our separate variables that are sent to [tbName] as the [value] parameter. On the Actions Editor side [value] will be an array where:
  • value[0] = whatever you set for [txt]
  • value[1] = whatever you set for [button1]
  • value[2] = the value of [button2] or an empty string ""
  • value[3] = the value of [objName] or an empty string ""
This is a much cleaner way to handle sending lots of data around. Strings like you are using is really best left for sending short pieces of data.

I think you will find that most of the anomalies you are running into will be related to how variables are being passed around and defined. You can imagine the immense complexity that exists keeping things predictable between JS, Actions Code, XML, and PowerPac functions. And all things considered, users see VERY few error messages when working with the PowerPac and ToolBook. Sometimes if a function fails, it is because the PowerPac assumed a default that the developer did not expect. No error pops up because the functions fails gracefully behind the scenes because the way it was executed was still legitimate; just not as expected by the end user.
 
Clifton
Site Admin
 
Posts: 732
Joined: Tue Jan 14, 2014 1:04 am

Re: calling funcions in an external JS file from within the

Postby John Robin Dove » Tue Aug 29, 2017 4:22 am

Hi Clifton,

Thank you for all the information. I had figured out some of this myself. My knowlefge tends to be empirical rather than rule-based. For example I knew that to test for null in the actions editor you can use: if A <> "" whereas in a javascript file you must use something like if (A).

I have used this to make a workaround that solves the problem:

Code: Select all
function tbfunction_showRequest(txt, button1, button2, objName) {
var varLine
  if (button2) {
    varLine = txt + "§" + button1 + "§" + button2 + "§";
  }
  else {
  varLine = txt + "§" + button1 + "§§";
  }
tbfunction_pgTBObjSet("translate", "user", varLine);
};


As for clunkiness; yes, you're right! There are unimaginable layers of clunkiness in my code. This particular example is used for something though. Field "translate" does two jobs. It either activates showRequest2 to show a fake dialog box or it shows a custom tool tip with shadow in the appropriate language. For tool tips I send a string separated by commas, for the dialog box I send a string separated by "§". I'm not saying this is logical or necessary but it works. When things work I tend to leave them alone.

Which brings me to my usual question: why were these errors not a problem in the past? I note that Javascript has a similar system to Option Strict in VB.NET https://www.w3schools.com/js/js_strict.asp I read here: The "use strict" directive is new in JavaScript 1.8.5 (ECMAScript version 5). It is not a statement, but a literal expression, ignored by earlier versions of JavaScript.
The purpose of "use strict" is to indicate that the code should be executed in "strict mode". With strict mode, you can not, for example, use undeclared variables.


Could it be that Java has decided to implement "use strict" or something like it in all cases nowadays? This might explain why this error and the snapObjectToCenter error did not stop execution in the past. If so I hope they don't come up with any more bright ideas like this!
John Robin Dove
 
Posts: 486
Joined: Thu Jan 23, 2014 4:35 am


Return to General Discussion

Who is online

Users browsing this forum: No registered users and 3 guests

cron