As part of the Read operation you normally have to implement some listing of available resources. Being familiar with JCR API it would be natural to do it with this JavaScript code in your ESP page
var iter = currentNode.getNodes();
while (iter.hasNext()) {
var childNode = iter.nextNode();
...
Yes, but no! The result is a big fat exception
org.mozilla.javascript.EcmaError: TypeError: hasNext is not a function, it is org.mozilla.javascript.Undefined. (/apps/catalog/html.esp#11)
Hm! currentNode is a JCR Node so getNodes() should return a javax.jcr.NodeIterator which is a java.util.Iterator. So the code looks correct but somehow
iter
here is not a Java object at all.I struggled with this several hours. I was very puzzled to see similar code in espblog sample working just fine. The only difference is that espblog uses QueryResult.getNodes() which still returns NodeIterator.
Finally I found the answer in this thread. It turns out Sling wraps Node.getNodes() to return a JavaScript object which has one property for each child node. Probably the idea was to easily iterate over that object with a for-each loop
for each (var childNode in currentNode.getNodes()) {
...
Another solution is to use the property name instead of the getter method
var iter = currentNode.nodes;
while (iter.hasNext()) {
var childNode = iter.nextNode();
...
This seems to circumvent the wrapping done by Sling.
This example illustrates a cute feature of Rhino which allows easy access of JavaBeans properties.
Yes, server side JavaScript can be fun.
I have to thank you sooooo much for posting this information! I just ran into this issue today, and could not find ANYTHING on it until I stumbled onto this post. I started trying every method with Node to try and debug the problem. It's not documented anywhere that I can find, and I don't know how you found the solution to the issue, but I can't thank you enough! :-)
ReplyDelete