Search code examples
javascriptfreemarkerecmascript-5nashornmagnolia

How do I reduce a list in a Magnolia JavaScript model?


I'm attempting to reduce a FreeMarker list in a Magnolia JavaScript model. I want all items that start with a capital "P".

[#assign list = ["Poker", "Pet", "Dog", "Cat", "Penguin", "Paddle", "punk"]]

My function should return:

["Poker", "Pet", "Penguin", "Paddle"]

Attempts

I attempted to use Array.prototype.reduce().

var Model = function() {
  this.reduceList = function(list) {
    return list.reduce(function(reducedList, item) {
      if (item.indexOf('P') !== -1) {
        reducedList.push(item);
      }
      return reducedList;
    }, []);
  }
};

new Model();
[#assign filteredList = model.reduceList(['Poker', 'Pet', 'Dog', 'Cat', 'Penguin', 'Paddle', 'punk'])]

However, I get the following error.

jdk.nashorn.internal.runtime.ECMAException: TypeError: list.reduce is not a function

Note: Magnolia JavaScript models are built on Nashorn.

Debugging

When I return the type of the list:

this.reduceList = function(list) {
  return typeof list;
}

I get an object:

object

When I return the list as a string:

this.reduceList = function(list) {
  return list.toString();
};

I get a list:

[Poker, Pet, Dog, Cat, Penguin, Paddle, punk]

How do I reduce a list in a Magnolia JavaScript model?


Solution

  • Use the filter() method. Here is a code sample:

    var Model = function() {
      this.reduceList = function(list) {
        return Java.from(list).filter(function(item) {
          return item[0] === 'P'
        });
      }
    };