Article John Kumpf · Jan 14, 2019 2m read

On a csp page, when you return %Boolean from a cache script into a javascript script, you're getting a string, not a boolean

This is a quick note on what happens when, on your CSP page, you call a cache script which returns a %Boolean and store that value in a javascript variable.

When you call a script with language="cache" and returntype="%Boolean" from a javascript script, the return value is interpreted as a string, not as a boolean.

Here's an example:

A cache script that returns (in theory) a "false" value:

<script language="cache" method="giveMeAFalse" arguments="" returntype="%Boolean" procedureblock='1'>
return 0
</script>

A javascript method that logs what the value's actually interpreted as:

<script language="javascript">
function isItActuallyFalse() {

var bool = #server(..giveMeAFalse());

console.log("bool = " bool);
console.log("bool ? 'truthy':'falsy' = "+(bool 'truthy':'falsy'));
console.log("typeof bool = ", typeof bool);
}

</script>

Output:

bool = 0

bool ? 'truthy':'falsy' = truthy

typeof bool = string

So bool is actually the string: "0", rather than the integer 0, or the boolean false.  Therefore, since bool is a string, it evaluates to truthy in Javascript, regardless of its contents.  Keep this in mind when returning values from cache methods into javascript methods.

If anyone knows of official documentation of this behavior somewhere, definitely link it.  I'm posting this so the next person who searches something like "cache script return type javascript csp" will hopefully hit some keywords, so it would be great if that hypothetical person also found an extended, official discussion of it.

Cheers.

Comments

Vitaliy Serdtsev · Jan 15, 2019

See zenConvertType() [///Converts a typed value returned from the server to an appropriate JS type] from zenutils.js.

Try this:

<script src="zenutils.js"></script>

<script language="javascript">
function isItActuallyFalse() {

var bool zenConvertType('BOOLEAN',#server(..giveMeAFalse())#);

...
}

</script>

<script language="cache" method="giveMeAFalse" arguments="" returntype="%Boolean" procedureblock='1'>return $$$NO</script>
or
var bool zenBool(#server(..giveMeAFalse())#);

... <<FONT COLOR="#ff0000">script </FONT><FONT COLOR="#000080">language</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800080">"cache" </FONT><FONT COLOR="#000080">method</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800080">"giveMeAFalse" </FONT><FONT COLOR="#000080">arguments</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800080">"" </FONT><FONT COLOR="#000080">returntype</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800080">"%Boolean" </FONT><FONT COLOR="#000080">procedureblock</FONT><FONT COLOR="#000000">=</FONT><FONT COLOR="#800080">'1'</FONT><FONT COLOR="#000000">></FONT><FONT COLOR="#0000ff">return </FONT><FONT COLOR="#008000">"false"</FONT><FONT COLOR="#000000"></</FONT><FONT COLOR="#ff0000">script</FONT><FONT COLOR="#000000">></FONT>

0
John Kumpf  Jan 15, 2019 to Vitaliy Serdtsev

This is great, thanks.  Just implemented it.  Worked like a charm.

Also let me just confirm (and this wasn't needed in my particular implementation): if I call giveMeAFalseMe from Cache when it's returning "true" or "false", Cache will translate "true" into a truthy %Boolean return value, right?

0
Vitaliy Serdtsev  Jan 16, 2019 to John Kumpf
if I call giveMeAFalseMe from Cache when it's returning "true" or "false", Cache will translate "true" into a truthy %Boolean return value, right?

No, it does zenBool, which is on the client side.

The important thing is that #server()# always returns a string, for example:

<script language="cache" method="giveMeAFalse" arguments="" procedureblock='1' returntype="%Integer">return 4</script>var bool #server(..giveMeAFalse())#;
console.log("bool = " bool);
console.log("typeof bool = "typeof bool);

Result:
bool = 4
typeof bool =  string
PS: you can further explore the sources of the #server()# -> cspHttpServerMethod() -> cspProcessResponse(), which are in the file cspxmlhttp.js.
0