Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session
SOLVED

Delegation Pattern for Sling Models doesn't populate all the properties from super class

Avatar

Level 1

I am trying to understand Delegation patterns better when we extend the core components Sling model.

I am following the example provided here https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models  to extend the Teaser component. Basically, I want all the properties defined in the Teaser component and add a few more. 

Whatever new properties I am adding to the custom sling model, I can access those, and they return the correct values. But the properties defined in the core component Teaser model return no value. Upon debugging, I noticed that values are being populated correctly in the private teaser property, so I thought of returning the whole Teaser object through the getter as shown in the below code snippet. (again, not sure if this is a good solution or not).

 

@Deleted Account
@Via(type = ResourceSuperType.class)
private Teaser teaser;

public Teaser getTeaser() {
    return teaser;
}

 

Now, I can access the core component's properties and read the values, but now my HTL looks ugly because to access the core component's properties, I have to write a teaser before those properties and not directly. 

 

<div data-sly-use.customTeaser="com.company.subdomain.core.models.CustomTeaser">
    <h2>${customTeaser.teaser.title}</h2>
</div>

 

I am sure I am doing something wrong here; that's why I wanted to reach out to the community to get some better ideas. Is there any other approach to extend a core component easily? Is something that needs to be done differently when implementing a delegation pattern to access core components properties without overriding each one?

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Faced a similar issue. Leaving a reply so that it helps others who come across the same problem.

 

The reason the core component properties are null is that currently, the above delegate sling model doesn't have access to core component properties. You will have to override all the helper methods, not just the ones you are modifying. For example, say you are not changing any logic related to 'title', still you will have to override getTitle().

 

@Override
public String getTitle() {
return Teaser.getTitle()
}

Or you can use Lombok to get rid of the boilerplate code.

 

https://blogs.perficient.com/2021/06/14/writing-less-java-code-in-aem-with-sling-models-lombok/

View solution in original post

6 Replies

Avatar

Community Advisor

@webdev24,

your code looks correct, can you show with us your implementation of the sling model using the delegation pattern?

Also make sure that your top level annotations are correct,

@Model(adaptables = SlingHttpServletRequest.class, adapters = Teaser.class, resourceType = "myproject/components/myTeaser")

Avatar

Correct answer by
Community Advisor

Faced a similar issue. Leaving a reply so that it helps others who come across the same problem.

 

The reason the core component properties are null is that currently, the above delegate sling model doesn't have access to core component properties. You will have to override all the helper methods, not just the ones you are modifying. For example, say you are not changing any logic related to 'title', still you will have to override getTitle().

 

@Override
public String getTitle() {
return Teaser.getTitle()
}

Or you can use Lombok to get rid of the boilerplate code.

 

https://blogs.perficient.com/2021/06/14/writing-less-java-code-in-aem-with-sling-models-lombok/

Avatar

Community Advisor

For any body who is trying to use the delegation pattern , the mistake you might be doing is with the Service you are importing in your HTL. For example if you are doing this approach 
https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models

 

In your HTL , do not import your custom model, but always use `

data-sly-use.title="com.adobe.cq.wcm.core.components.models.Title  

the core components Model

 

If you use your Model , then as @JeevanRaj was mentioning , you will have to ovveride every method in the Core Model Interface. 

 

 So in your case instead of using 

 

data-sly-use.customTeaser="com.company.subdomain.core.models.CustomTeaser"

 

, if you use  

data-sly-use.teaser="com.adobe.cq.wcm.core.components.models.Teaser" 

It will work, because you have written the Model to run when the resource Type is 

resourceType = "myproject/components/myTeaser"

Avatar

Community Advisor

Hi @VeenaVikraman 

 

In case the core component model is used in the HTL, we will have to override all the methods(or use Lombok).

 

data-sly-use.title="com.adobe.cq.wcm.core.components.models.Title 

Never tried using the custom model in HTL for Sling delegation.

Avatar

Community Advisor

I am working with core components right now and I am also using the delegation pattern. But I didn't face the issue which you are mentioning @JeevanRaj .

Avatar

Community Advisor

@JeevanRaj I got why you have to ovveride all the methods. 

 

https://github.com/adobe/aem-core-wcm-components/wiki/Delegation-Pattern-for-Sling-Models In this if you add `@delegate` along with below

@Delegate @Self @Via(type = ResourceSuperType.class)
    private Title title;

then you need not ovveride any methods

But if you have to rewrite the logic of any of the existing methods, you should not use @Delegate and ovverride all the methods.

 

Thanks

Veena ✌