birt
birt copied to clipboard
Execute Javascript error
birt version : 4.9.0
my expression: replaceSubScript(row["tp"])
A javascript file is referenced in the report
function replaceSubScript(str) {
if (!str && typeof(str)!="undefined" && str!=0) {
return "";
}
return str.replace("₂", "<SUB>2</SUB>");
}
Running the report gives an error: detail : org.eclipse.birt.report.engine.api.EngineException: Invalid javascript expression: TypeError: Cannot find default value for object.
i change
return str.replace("₂", "<SUB>2</SUB>");
to
return String(str).replace("₂", "<SUB>2</SUB>");
Running the report without errors
It looks like your if
condition is wrong.
You probably want to write:
function replaceSubScript(str) {
if (!str) {
return "";
}
return str.replace("₂", "<SUB>2</SUB>");
}
The !
operator will return true for an empty string, undefined
and null
.
Or dou you really want to compare a string to the number zero?
Besides, always be very careful when using string methods, in particular replace
.
This is probably one of the cases where Rhino causes difficulties.
To recap: BIRT uses Javascript for logic inside the reports. BIRT uses Java internally. The Javascript engine is Rhino - a Javascript implementation written in Java. Rhino allows to acces Java objects from Javascript more or less seamlessly.
Not sure, but I think that the column bindings are actually Java objects, not Javascript objects.
This is a typical example of the "less" case.
Let us assume that the if condition is false and the expression str.replace(..., ...)
is actually evaluated.
The replace
methods of a Java string and a Javascript string differ significantly:
The Javascript method expects a regular expression as the first argument (or a string).
The Java method expects either a Java String or a Java CharSequence object as the first argument.
If str
is null
or a Javascript number
object, e.g. 3.14 or whatever:
Original code: Its replace
method cannot be called.
With String(str)
: The String
constructor will always return a Javascript string "null" or "3.14", and then its (Javascript) replace
method is called.
If str
is a Javascript string, then String(str)
is basically a no-op:
Original code: The Javascript replace
method is called.
With String(str)
: ditto.
If str
is a Java string:
Original code: Rhino has to guess what you mean, because the Java String class has different replace
methods. This probably results in an error message or an exception (I stumbled across this several times myself).
With String(str)
: The String
constructor returns an equivalent Javascript string, then its (Javascript) replace
method is called.
If str
is any other Java object:
Original code: Will fail (if we assume that the Java class has no replace
method)
With String(str)
: I don't know what happens.
Note: I'm not absolutely sure here. Javascript as a programming language is still a kind of mystery to me.
I am using the following functions in our reports (comments are in german). They'll allow you to write "The chemical formula for water is H_2O. 3 <= Pi <= 4. A well-known constant is: 6.023 * 10^{23}'. This is a tiny subset of LaTeX syntax.
I am using ("" + text")
therein which has more or less the same effect as String(text)
.
function escapeHtml(plaintext) {
if (plaintext == null) {
return "";
}
return (""+plaintext).replace(/[&<>"']/g, function (s) {
var entityMap = {
"&": "&",
"<": "<",
">": ">",
'"': '"',
"'": '''
};
return entityMap[s];
});
}
/**
*** Ersetzt gängige Formen mathematischer Operatoren durch die entsprechenden Unicode-Symbole.
**/
function math_symbols(text) {
if (!text) {
return text;
}
return (""+text).replace(/\>\=/g, "≥").replace(/\<\=/g, "≤").replace(/\!\=/g, "≠").replace(/\\sum/g, "\u2211");
}
/**
*** Mit _ und ^ können hoch- und tiefgestellte Texte erzeugt werden,
*** entweder einzelne Buchstaben/Ziffern oder Gruppen mit {}, Z.b H_2O oder H_{2}O.
*** Das ersetzt natürlich kein LaTeX.
*** Die Eingabe ist plaintext im o.g. Format, die Ausgabe HTML.
**/
function chem_formel(text) {
if (!text) {
return text;
}
var html = escapeHtml(math_symbols(text));
var html = html.replace(/_{([^}]+)}/g, "<sub>$1</sub>");
var html = html.replace(/_(.)/g, "<sub>$1</sub>");
var html = html.replace(/\^{([^}]+)}/g, "<sup>$1</sup>");
var html = html.replace(/\^(.)/g, "<sup>$1</sup>");
log.debug("chem_formel " + text + " => " + html);
return html;
}
@hvbtup Well, there are some problems with if judgment, which has been fixed