This is an automated email from the ASF dual-hosted git repository.
hansva pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/hop.git
The following commit(s) were added to refs/heads/main by this push:
new ee730a3ed4 Document stream fields as wrapped Java objects in the
JavaScript transform (#8166)
ee730a3ed4 is described below
commit ee730a3ed4a7e4aa8eb47660ce50217c4297ffa0
Author: Sergio Ramazzina <[email protected]>
AuthorDate: Sat Aug 29 11:51:50 2026 +0200
Document stream fields as wrapped Java objects in the JavaScript transform
(#8166)
Stream fields are added to the Rhino scope through Context.toObject(), so
they reach the script as wrapped Java objects instead of JavaScript
primitives. This makes a Boolean field always truthy and makes == / !=
between two fields compare object identity rather than values.
Add a "Stream fields are Java objects" section to the JavaScript transform
documentation describing the behaviour and the .valueOf() / parseInt()
workarounds, including the null-safety check.
---
.../ROOT/pages/pipeline/transforms/javascript.adoc | 41 ++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git
a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/javascript.adoc
b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/javascript.adoc
index 80ad0e901a..5d6cfdc22c 100644
---
a/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/javascript.adoc
+++
b/docs/hop-user-manual/modules/ROOT/pages/pipeline/transforms/javascript.adoc
@@ -248,6 +248,47 @@ Fields must be added to the rows in the same order to keep
the structure of the
To add a field, define it as var in the Javascript pane, and add it as a field
in the Fields table.
+=== [[stream-fields]]Stream fields are Java objects
+
+Fields coming from the input stream are not plain JavaScript primitives: the
transform hands them to the Rhino engine as *wrapped Java objects*
(`java.lang.Boolean`, `java.lang.Long`, `java.lang.String`, and so on).
Variables you declare yourself with `var` inside the script are plain
JavaScript values instead. That difference explains a number of surprising
results, and `typeof` makes it visible:
+
+[source, javascript]
+----
+var myBoolean = false;
+
+typeof(myBoolean); // "boolean" - declared in the script
+typeof(booleanField); // "object" - coming from the stream
+----
+
+Two consequences are worth knowing about.
+
+*A Boolean field is always truthy.* Rhino treats any wrapped object as `true`,
so an `if` on a Boolean field never takes the else branch, even when the field
is `false`. Comparing explicitly with `true` does work, because the equality
operator unwraps the object:
+
+[source, javascript]
+----
+if (booleanField) { ... } // ALWAYS true, even when the field is
false
+if (booleanField == true) { ... } // correct
+if (booleanField.valueOf()) { ... } // correct
+----
+
+*Comparing two fields with `==` or `!=` compares object identity, not values.*
Two Integer fields holding the same number are still two distinct Java objects,
so `!=` reports them as different. Force a conversion to a JavaScript value
first:
+
+[source, javascript]
+----
+if (intFieldA != intFieldB) { ... } // WRONG: compares
references
+if (intFieldA.valueOf() != intFieldB.valueOf()) { ... } // correct
+if (parseInt(intFieldA) != parseInt(intFieldB)) { ... } // correct
+----
+
+As a rule of thumb, call `.valueOf()` (or `parseInt()`, `parseFloat()`,
`String()`) on a stream field whenever you use it in a comparison or in a
boolean test.
+
+A field that is null in the stream is put in the script scope as `null`.
Testing it with `fieldName == null` is safe, but calling any method on it -
including `.valueOf()` - fails, so check for null first:
+
+[source, javascript]
+----
+var flag = (booleanField != null) && booleanField.valueOf();
+----
+
=== [[numeric-values]]Numeric values
Most values that are assigned in JavaScript are floating point values by
default, even if you think you have assigned an integer value. If you are
having trouble using == or switch/case on values that you know are integers,
use the following constructs: