Jelly: Some Variables are More Equal than Others...
Import
·
Dec 12, 2011
·
article
- Jelly: This may surprise you, but…Jelly doesn't know about JavaScript variables at all. It only knows about Jelly variables. Jelly itself doesn't actually care what the names of Jelly variables are, but nevertheless when using Jelly on the ServiceNow platform, it's vital to start the name of every Jelly variable with the prefix jvar_, which you'll see used throughout the out-of-the-box Jelly templates. In Jelly, this naming convention allows some optimization — but in JEXL (as you'll see below) it is imperative.
- JEXL: On the ServiceNow platform, JEXL will work with either Jelly variables or JavaScript variable. Standard JEXL only works with Jelly variables, but ServiceNow has extended it to work with both. The mechanism is simple (pay attention, this is important!
if the variable name starts with jvar_, JEXL assumes it's a Jelly variable. Otherwise, JEXL assumes it's a JavaScript variable. This has some consequences. For example, if you create a JavaScript variable that starts with jvar_, JEXL won't know it's there. Also, if you create a Jelly variable that doesn't start with jvar_, JEXL won't know it's there. Bottom line: follow the Jelly variable naming convention, and you won't get hurt. - JavaScript: Of course JavaScript knows about its own variables — but it can also know about Jelly variables, through the jelly="true" attribute I introduced in an earlier post. There's a catch, though: JavaScript can read (look at the values of) Jelly variables, but it cannot write (change the values of) or create Jelly variables. This happens because of the way that jelly="true" attribute actually works: it copies the Jelly variables into JavaScript variables. You can modify the JavaScript variable all you want — but the changes you make won't be copied back to the Jelly variables.
Here's an example of several easy-to-make mistakes regarding Jelly and JavaScript variables:
var colors = ['Red', 'Black', 'Blue', 'Brown', 'CadetBlue', 'DarkGreen', 'DeepPink']; var jvar_test = 'test'; jelly.jvar_alpha = 'ALPHA'; jelly.jvar_beta = 'BETA';Color: $[SP] ${color}
test: ${jvar_test}
alpha: ${jvar_alpha}
beta: ${jvar_beta}
This goes horribly wrong in several ways. We'll take 'em one at a time:
- The evaluate tag has the jelly="true" attribute, so the Jelly variable jvar_alpha defined on the preceding line gets copied into the jelly variable (as jelly.jvar_alpha). That part works just fine. In the script we attempt to change the value of that property (with jelly.jvar_alpha = 'ALPHA';. We also try to create a new Jelly variable (with jelly.jvar_beta = 'BETA';). Near the end of the Jelly template, we try inserting these Jelly variables into paragraphs — and if you run this as a UI Page, you'll see that it does not work.
- Inside the evaluate tag, you can see the line var jvar_test = 'test';. This looks like we're trying to set the value of a Jelly variable, but actually what we're doing is setting the value of a JavaScript variable whose name happens to look like the name of a Jelly variable. Near the end of the Jelly template you can see where we try to insert that variable into a paragraph — and it works very poorly indeed. This fails because JEXL expression ${jvar_test} sees that the name starts with jvar_ and assumes that it's a Jelly variable — one that doesn't actually exist. Fail.
- Now look at the tag j:forEach items="${colors}" var="color". This is going to iterate over the JavaScript array j:forEach items="${colors}" var="color" and put each value it iterates over into the variable color. It's that variable name that poses a problem: the name coloris a valid Jelly variable name, so Jelly works just fine with it. But a little later (in
Color: $[SP] ${color}
), we use that variable name in JEXL expressions — and those try to look up the value in a JavaScript variable (because the variable name doesn't start with jvar_). This is a good example of a bad thing that can happen because you didn't start a Jelly variable's name with jvar_.
Just for fun, here's the same thing with all the problems fixed. Note the use of JEXL expressions to move JavaScript values into Jelly variables:
var colors = ['Red', 'Black', 'Blue', 'Brown', 'CadetBlue', 'DarkGreen', 'DeepPink']; var test = 'test'; var alpha = 'ALPHA'; var beta = 'BETA';Color: $[SP] ${jvar_color}
test: ${jvar_test}
alpha: ${jvar_alpha}
beta: ${jvar_beta}
I hope that's quite enough on this subject, Burt! Did you wash your face yet?
View original source
https://www.servicenow.com/community/in-other-news/jelly-some-variables-are-more-equal-than-others/ba-p/2281152