Your achievements

Level 1

0% to

Level 2

Tip /
Sign in

Sign in to Community

to gain points, level up, and earn exciting badges like the new
Bedrock Mission!

Learn more

View all

Sign in to view all badges

Adobe Summit 2023 [19th to 23rd March, Las Vegas and Virtual] | Complete AEM Session & Lab list
SOLVED

SlingModel @ChildResource is not working

Avatar

Level 4

Hi All,

 

I have a node called "entries" under the page. The "entries" node having some child nodes like entry1, entry2, entry3. The "entries" and child nodes "entry1" have been creating via code and I don't have any component for this. Now, I'm trying to access the "entries" node in a sling model but it's not working. Below is the screenshot of the node structure,

 

Screenshot 2020-07-28 at 12.08.19 PM.png

 

Below is the code,

 

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

private static final Logger LOGGER = LoggerFactory.getLogger(HistoryModel.class);

@Self
private Resource currentResource;

/*@ChildResource(name = "entries")
private List<HistoryBean> entries;
*/
@ChildResource(name = "entries")
private Resource entries;

@ChildResource(name="entries",injectionStrategy= InjectionStrategy.OPTIONAL,via = "resource")
Resource child;

public Resource getEntries() {
return entries;
}

public Resource getChild() {
return child;
}

@PostConstruct
protected void postConstruct() {
//Nothing inside
LOGGER.debug("HistoryModel post construct Method().. calling..");
LOGGER.debug("HistoryModel entries.. calling..{}", entries);
LOGGER.debug("HistoryModel child.. calling..{}", child);

}

Tried with @childResource. In the log, I'm getting null. anything wrong in the code? Can anyone help?

 

@arunpatidar26 @smacdonald2008 @arunpatidar26 @Ratna_Kumar @kautuk_sahni @wimsymons @cqsapientu69896 @vanegi @Veena_Vikram @varuns7990 @Theo_Pendle

 

Thanks,

Vijay

Topics

Topics help categorize Community content and increase your ability to discover relevant content.

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Hi @vijays80591732 ,

 

If this is not a component and you want to access it in Sling Model, then you can make use of a java class to read its child values and return in Sling Model in this way:

 

@Getter
@Setter
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class HistoryModel {

@Inject
private List<WorkflowItem> workflowItems;

@Self
private transient Resource resource;

@PostConstruct
private void init() {
workflowItems = SomeUtilClass.getWorkflowItems(resource, "path to entries node");
}
}
 
And your Util Class method can have this code:
List<WorkflowItem>workflowItemsList = Collections.emptyList();
Resource workflowResource = resource.getResourceResolver().getResource("path to entries");
if (workflowResource != null && workflowResource.hasChildren()) {
workflowItemsList =
Lists.newArrayList(workflowResource.getChildren()).stream()
.map(child -> child.adaptTo(WorkflowItem.class))
.collect(Collectors.toList());
return workflowItemsList;
}
 
WorkflowItem class can be another Model class with Description and Message and other attributes as per your need.
0 Replies

Avatar

Correct answer by
Community Advisor

Hi @vijays80591732 ,

 

If this is not a component and you want to access it in Sling Model, then you can make use of a java class to read its child values and return in Sling Model in this way:

 

@Getter
@Setter
@Model(adaptables = Resource.class, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)
public class HistoryModel {

@Inject
private List<WorkflowItem> workflowItems;

@Self
private transient Resource resource;

@PostConstruct
private void init() {
workflowItems = SomeUtilClass.getWorkflowItems(resource, "path to entries node");
}
}
 
And your Util Class method can have this code:
List<WorkflowItem>workflowItemsList = Collections.emptyList();
Resource workflowResource = resource.getResourceResolver().getResource("path to entries");
if (workflowResource != null && workflowResource.hasChildren()) {
workflowItemsList =
Lists.newArrayList(workflowResource.getChildren()).stream()
.map(child -> child.adaptTo(WorkflowItem.class))
.collect(Collectors.toList());
return workflowItemsList;
}
 
WorkflowItem class can be another Model class with Description and Message and other attributes as per your need.

Avatar

Community Advisor

@vijays80591732 

try with 

@ChildResource(injectionStrategy = InjectionStrategy.OPTIONAL)

Collection<Resource> entries

 

Hope this will help

Avatar

Level 4

Thanks Suraj for your inputs. I have created a component and calling that from template.html. Now, getting the current resource and fetching the child nodes.