javaaemslingaem-6sling-models

AEM Multifield - Modifying values in multifield values


Multifield issue

NotificationAlert.java

@Model(adaptables = {SlingHttpServletRequest.class,
        Resource.class}, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class NotificationAlerts {

 @Inject
    @Via("resource")
    @Default(values = CommonConstants.EMPTY)
    @Named("notificationItems")
    private List<ListingModel> notificationItems;

    public List<ListingModel> getNotificationItems() {
        return notificationItems;
    }

    public void setNotificationItems(List<ListingModel> notificationItems) {
        this.notificationItems = notificationItems;
    }

@PostConstruct
    private void initModel() {
       for(ListingModel model : notificationItems)
       {
         String createTime = model.getCreateTime();
         String formattedTime = changeDateFormat(createTime); 
//When I debugged I got the formattedTime correctly
//But not setting below
         model.setCreateTime(formattedTime); 
       }
    }

String changeDateFormat(String dateValue)
{
//definiton
}
}

And the ListingModel.java Interface

@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public interface ListingModel {

@Inject
    String getNotificationLogo();
    
    @Inject
    String getCreateTime();

    public void setCreateTime(String value);
    
    @Inject
    boolean isActive();

}

I have tried declaring a setter function in the interface and try calling it in @PostConstruct.

But it is not changing

I want to format the createTime using changeDateFormat(String value)

Or can I call the changeDateFormat() in sightly ?

How do I do it ?

Thanks in advance

Edit : I want to know how to modify the createTime value as edited in @PostConstruct. The setter is not setting anything.

Also, there is a setter method in the interface


Solution

  • When creating a sling model from an interface as opposed to a class, sling only implements getters annotated with @Inject. Anything else is stubbed out with dummy no-op implementations, which is why the setter doesn’t do anything.

    If you want the setter to work, make ListingModel a class instead of an interface and inject fields instead of methods.

    Then, you can add your own getters and setters to the ListingModel and they can modify the field, if desired:

    @Model(
        adaptables = Resource.class,
        defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL
    )
    public class ListingModel {
        @Inject
        private String notificationLogo;
        
        @Inject
        private String createTime;
        
        @Inject
        private boolean active;
    
        public String getNotificationLogo() {
            return notificationLogo;
        }
    
        public String getCreateTime() {
            return createTime;
        }
    
        public String isActive() {
            return active;
        }
    
        public void setCreateTime(String value) {
            this.createTime = value;
        }
    }
    

    If the logic to format the create time isn’t dependent on anything in NotificationAlerts, you could even maybe do the formatting on the fly in the getCreateTime method, thus removing the need to have a setter at all or a @PostConstruct method on NotificationAlerts.