Search code examples
javascriptfreemarkerecmascript-5nashornmagnolia

Why does Array.prototype.filter() throw an error in Magnolia JavaScript models?


I'm attempting to filter a FreeMarker list in a Magnolia JavaScript model using Array.prototype.filter().

List

[#assign list = [1, 2, 3]]

Model

var Model = function() {
  this.filterList = function(list) {
    return list.filter(function(item) {
      return item === 2
    });
  }
};

new Model();

Usage

${model.filterList(list)}

However, I get the following error.

Caused by: jdk.nashorn.internal.runtime.ECMAException: TypeError: list.filter is not a function

Nashorn was implemented using ECMAScript-262 5.1.

The Nashorn JavaScript engine was first incorporated into JDK 8 via JEP 174 as a replacement for the Rhino scripting engine. When it was released, it was a complete implementation of the ECMAScript-262 5.1 standard. — JEP 335: Deprecate the Nashorn JavaScript Engine

Why despite the fact that Nashorn follows ECMAScript-262 5.1 do I get an error when using Array.prototype.filter()?


Solution

  • The FreeMarker list you are passing to the model is a sequence, not a JavaScript array.

    Sequence (3)
      0 = 1 (BigDecimal)
      1 = 2 (BigDecimal)
      2 = 3 (BigDecimal)
    

    To solve the issue, convert the FreeMarker list you are passing to the model to a JavaScript array using Java.from(). For example:

    var Model = function() {
      this.filterList = function(list) {
        return Java.from(list).filter(function(item) {
          return item === 2
        });
      }
    };
    
    new Model();