Expand my Community achievements bar.

Delegation Pattern for Sling Models returns null object

Avatar

Community Advisor

I am trying to delegate core navigation component for my proxy navigation component. I have used below code snippet for that purpose in my sling model class.

@Deleted Account
@Via(type = ResourceSuperType.class)
private Navigation nav;

 

But  this type of injection is providing null object when creating model object using modelfactory. Any suggestion would be helpful.

8 Replies

Avatar

Community Advisor

HI @Asutosh_Jena_ 

I have followed the same approach as mentioned the article provided by you. However, I am facing issue when I am trying to instantiate my custom model class using below line of codes:

NavigationCustomModel navigation= resource.adaptTo(NavigationCustomModel.class);

Above returns navigation as null.

Avatar

Level 4

Hi @TarunKumar ,

 

In order to use sling delegation, you have to have adaptable of your sling model as SlingHttpServletRequest and resourceType property in model annotation.

 

your component should have property slingResourceSuperType pointed to right component.

 

https://aemexplained.wordpress.com/aem-guide/extending-component-using-sling-delegation/ 

 

In your case whatever the resource you are trying to adapt. It should point to a component which has this slingResourceSuperType in it.

 

if you can share sample model class how you are trying to do. I can help you. (Also component xml under apps is needed)

 

Thanks!

Avatar

Community Advisor

Hi @MohitKumarK 

Please find the model class code snippet that I am using:

@Model(adaptables = { SlingHttpServletRequest.class}, adapters = {ComponentExporter.class,Navigation.class,NavigationCustomModel.class },
resourceType = "myproject/components/content/navigation", defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = "gson", extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class NavigationCustomModel implements Navigation {

private static final Logger LOGGER = LoggerFactory.getLogger(NavigationCustomModel.class);
private static final String PN_ACCESSIBILITY_LABEL = "accessibilityLabel";

 

@Self
private SlingHttpServletRequest request;


@Self
@Via(type = ResourceSuperType.class)
@Delegate(excludes = DelegationExclusion.class)
private Navigation navigation;

/**
* The current page.
*/
@ScriptVariable
private Page currentPage;

/**
* The current style.
*/
@ScriptVariable
private Style currentStyle;

/**
* The language manager service.
*/
@OSGiService
private LanguageManager languageManager;

/**
* The relationship manager service.
*/
@OSGiService
private LiveRelationshipManager relationshipManager;

/**
* The accessibility label.
*/

private String accessibilityLabel;


@Inject
private Resource resource;


@JsonIgnore
private List<NavigationItem> items;


static final String PN_DISABLE_SHADOWING = "disableShadowing";

/**
* Initialize the model.
*/
@PostConstruct
private void initModel() {
ValueMap properties = this.resource.getValueMap();
items = getItems();
}

 

@Override
public List<NavigationItem> getItems() {
return nav.getItems();
}

@Override
public String getAccessibilityLabel() {
if (this.accessibilityLabel == null) {
this.accessibilityLabel = this.resource.getValueMap().get(PN_ACCESSIBILITY_LABEL, String.class);
}
return this.accessibilityLabel;
}

And in servlet I am trying to initiate the object of this model class using adapt to but I am getting null value.:-

Resource resource = req.getResourceResolver().getResource("/content/hq/en/testpage");
NavigationCustomModel navigation = resource.adaptTo(NavigationCustomModel.class);

Avatar

Level 4

Hi @TarunKumar ,

As per your sling model, you are extending for navigation component. But you are trying to adapt a page as your navigation model. May be thats the reason you are getting null. Try to adapt a resource which is of type (myproject/components/content/navigation).

Remember this navigation component should extend (sling:resourceSuperType) as core navigation component.

Thanks!

Avatar

Community Advisor

Hi @MohitKumarK 

Thanks for your reply. I have tried adapting to resource "myproject/components/content/navigation" as well but this also doesn't serve the purpose and my navigation object appear as null.

Also attached is the screen print of my navigation component which is extending the core navigation component.

Tarun202_0-1637043217331.png

 

 

Avatar

Level 4

@TarunKumar ,

Resource resource = req.getResourceResolver().getResource("/content/hq/en/testpage");

in this line what ever the path you are giving, that resource should be of type myproject/components/content/navigation.

 

Avatar

Level 1

Hi,

Any update about this ?

I am also facing the same problem.

Delegation pattern works fine except when adapting a resource to the model using delagation.

 

Regards,

 

Francis BONHEUR.