user3870265
user3870265

Reputation: 63

AEM multifield data-sly-repeat ${item} not working

This has been driving me nuts - hoping someone can help me.

I have a multifield component called 'books' with a single textfield: 'title'.

Everything seems to be working; the dialog box contains the multifield then I add two title fields then enter 'title1' and 'title2'.

then in the HTML itself I go:

<div data-sly-repeat="${properties.books}">
  <p>${item}</p>
  <p>${itemList.index</p>
  <p>${item.title}</p>
</div>

What I don't get is, ${item} correctly gives me: {"title": "title1"} {"title": "title2"}

and ${itemList.index} correctly gives me: 0 1

but ${item.title} keeps coming up blank. I also tried ${item["title"]} and that comes up blank too.

What am I doing wrong here? In my desperation I contemplated using

<div data-title="${item}"></div>

and then using JS to process the JSON object but I don't really want to do that.

Someone help, please!

Upvotes: 1

Views: 2852

Answers (1)

Ahmed Musallam
Ahmed Musallam

Reputation: 9753

It looks like your books property is either a JSON array string or a multivalued property with each value being a JSON object string;

The easiest way to parse the property is via a JS model like the following:

You could simplify this script to match your specific case, I made it general to multi-value and non-multi-value string properties.

/path/to/your-component/model.js:

"use strict";
use(function () {

    // parse a JSON string property, including multivalued, returned as array
    function parseJson(prop){
        if(!prop) return [];
        var result =[];
        if(prop.constructor === Array){
            prop.forEach(function(item){
                result.push(JSON.parse(item));
            });
        }
        else {
            var parsed = JSON.parse(prop);
            if(parsed.constructor === Array){
                result = parsed;
            }
            else result = [parsed];
        }
        return result;

    }

    var $books = properties.get("books", java.lang.reflect.Array.newInstance(java.lang.String, 1));
    var books = parseJson($books);

    return {
        books: books
    }

});

/path/to/your-component/your-component.html:

<sly data-sly-use.model="model.js"/>
<div data-sly-repeat="${model.books}">
  <p>${item}</p>
  <p>${itemList.index</p>
  <p>${item.title}</p>
</div>

Upvotes: 2

Related Questions