Expand my Community achievements bar.

SOLVED

Use adaptTo to transform the Resource to Custom Class

Avatar

Level 3

Hi, Guys,

 

I am new to AEM and I am facing a problem about converting Resource to Custom Model.

 

//--------------------------------------------------

ResourceResolver resourceResolver = request.getResourceResolver();
Resource resource = resourceResolver.getResource(path);
//--------------------------------------------------
 
I use the function above to get the Resource, then I use adaptTo to tranform Resource to CustomText Class.
 
//--------------------------------------------------
customText = resource.adaptTo(CustomText.class);
//--------------------------------------------------
 
But the result is null although I can get very property from getValueMap Method. But I cannot 
convert it to custom class.
 
For my current task is that:
1. I have Page A contains Component A and Page B contains Component B
2. I want to get the Component B json or Java instance in Page A or Component A to render the Component B
    with Page A together.
 
It is very appreciated if you guys can help me to solve problem or give me some advice to solve.
Thank you very much.
1 Accepted Solution

Avatar

Correct answer by
Level 9

Hi @TrifaCh  

Data sly resource will include the component as a whole. If you want to just read one property from another component in a different page this will not help. 

 

You can get to that page and iterate over resources and read that property .See a similar snippet in below URL.

https://stackoverflow.com/questions/70384076/how-to-access-the-properties-of-a-component-from-anothe...

View solution in original post

8 Replies

Avatar

Community Advisor

Hi @TrifaCh, Can you share your CustomText class implementation? It will be easier to understand the issue.

In some cases, the adaptTo() method might return null due to various reasons, which include:

  • make sure adapters (CustomText) utilize the @Model annotation as with the parameter adaptables set to Resource.class: @Model(adaptables = Resource.class)
  • the implementation does not support the target type
  • an adapter factory handling this case is not active (for example, due to missing service references)
  • internal condition failed
  • service is not available

For more details, you can refer to the documentation at: Adobe Experience Manager - Sling Adapters

Avatar

Level 3
@Model(adaptables = SlingHttpServletRequest.class, adapters = { CustomText.class,
        ComponentExporter.class }, resourceType = CustomTextImpl.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
@Exporter(name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)
public class CustomTextImpl implements CustomText {
    static final String RESOURCE_TYPE = "application/components/text";

    @ValueMapValue
    private String text;

    @ValueMapValue
    private int size;

    @Self
    private SlingHttpServletRequest request;

    @Override
    public String getText() {
        return text;
    }

    @Override
    public int getSize() {
        if (size > 0){
            return size;
        }
        return 14;
    }

    @Override
    public String getExportedType() {
        return CustomTextImpl.RESOURCE_TYPE;
    }
}

Avatar

Community Advisor

Hi @TrifaChYou are currently adapting Resource to CustomText; however, the Resource.class is absent in the @Model adaptables properties. To resolve this, make sure to include Resource.class in the @Model annotation's adaptable properties. This addition will enable the adaptation of Resource to CustomText.

// SlingHttpServletRequest not required since no use of request
@Model(adaptables = Resource.class
  ....)

 

 

Avatar

Level 3

Thank you for replying. There are some component can be adapted from Resource after adding it. However, some components still not work. Maybe there are other reasons affect the progress of adapting.

Avatar

Level 9

Hi @TrifaCh 

Sling offers an Adapter pattern to conveniently translate objects that implement the Adaptable interface. This interface provides a generic adaptTo() method that translates the object to the class type being passed as the argument. In your case it returns a null because I believe the implementation is not supported here .

Please read the below documentation to know more about supported resource adaptions

https://experienceleague.adobe.com/docs/experience-manager-65/developing/platform/sling-adapters.htm...

 

On the tasks you had queries 

Components are independent of pages. If both the components are allowed on the templates that is used to create page A and page B you can directly add component B in page A if its allowed in layout container policies.

 

 

Another approach is you can include component B through code . Place the code on the template for page A or in component A html

eg.

<sly data-sly-resource="${resource @ resourceType='wcm/foundation/components/responsivegrid'}"></sly>

where "wcm/foundation/components/responsivegrid" is path to your component.

 

 

Hope this helps

Avatar

Level 3

Thank you for replaying. But I have a question about implementation.

 

<sly data-sly-resource="${resource @ resourceType='wcm/foundation/components/responsivegrid'}"></sly>

 How should I access the resource of component B? For example, there is a get function in component B, how should I call it in the component A.

 

Thank you very much.

Avatar

Correct answer by
Level 9

Hi @TrifaCh  

Data sly resource will include the component as a whole. If you want to just read one property from another component in a different page this will not help. 

 

You can get to that page and iterate over resources and read that property .See a similar snippet in below URL.

https://stackoverflow.com/questions/70384076/how-to-access-the-properties-of-a-component-from-anothe...

Avatar

Level 3

Thank you very much. I think your sharing is useful. I may need to use it in the future.