Dynamic Dropdown using datasource | Community
Skip to main content
Level 3
November 6, 2024
Solved

Dynamic Dropdown using datasource

  • November 6, 2024
  • 2 replies
  • 1663 views

Hi,

I have a dynamic dropdown that is populated using a datasource. In my servlet, I use a ResourceResolver obtained from a service user instead of the request object(this is done to avoid granting permissions to individual group users.). Although I can successfully retrieve the values on the backend with the service user, they are not displaying in the component dialog on the frontend.
All necessary permissions are granted to the service user, and the datasource object contains values. However, it is not appearing on the frontend.I suspect the issue arises when executing request.setAttribute(DataSource.class.getName(), ds);

It functions correctly when the ResourceResolver is obtained from the current request object.
Below is the code snippet. Any help is appreciated.


try (ResourceResolver resolver = ResourceResolverUtils.getDefaultServiceResourceResolver(resourceResolverFactory)) {

request.getSession().setAttribute(DataSource.class.getName(), EmptyDataSource.instance());
List<String> subGroupList = userGroupRetriever.getUsersAndGroups(resolver, parentGroupName, true);

List<Resource> fakeResourceList = new ArrayList<>();
for (String subGroup : subGroupList) {
ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("value", subGroup.trim().toLowerCase());
vm.put("text", subGroup.trim());
fakeResourceList.add(new ValueMapResource(resolver, new ResourceMetadata(), JcrConstants.NT_UNSTRUCTURED, vm));
}

DataSource ds = new SimpleDataSource(fakeResourceList.iterator());

request.getSession().setAttribute(DataSource.class.getName(), ds);

// request.setAttribute(DataSource.class.getName(), ds);
} catch (Exception e) {
log.error("Exception occurred {}", ExceptionUtils.getStackTrace(e));
}

@estebanbustamante 

This post is no longer active and is closed to new replies. Need help? Start a new post to ask your question.
Best answer by EstebanBustamante

Hi, 

I think you’re right; the issue may be related to the resourceResolver and the permissions granted to it. Try using "your" resourceResolver solely to gather the items you need to display in the dialog. Try something like this:

try (ResourceResolver resolver = ResourceResolverUtils.getDefaultServiceResourceResolver(resourceResolverFactory)) { ResourceResolver originalResolver = request.getResourceResolver(); request.getSession().setAttribute(DataSource.class.getName(), EmptyDataSource.instance()); List<String> subGroupList = userGroupRetriever.getUsersAndGroups(resolver, parentGroupName, true); List<Resource> fakeResourceList = new ArrayList<>(); for (String subGroup : subGroupList) { ValueMap vm = new ValueMapDecorator(new HashMap<>()); vm.put("value", subGroup.trim().toLowerCase()); vm.put("text", subGroup.trim()); //Note here the resolver changed fakeResourceList.add(new ValueMapResource(originalResolver, new ResourceMetadata(), JcrConstants.NT_UNSTRUCTURED, vm)); }

 

Ultimately, I think the best way to troubleshoot this is by debugging, adding some breakpoints, and seeing what's happening.

 

Hope this helps

 

 

2 replies

arunpatidar
Community Advisor
Community Advisor
November 6, 2024

Hi @divyat3 
Could you please check if this code is being called on dialog load.

Could you share how did you linked this servelt/datasourcetype with component.

 

Here is the example code using servlet

https://github.com/arunpatidar02/aem63app-repo/blob/master/java/DemoDailogDropdown.java 

Arun Patidar
DivyaT3Author
Level 3
November 6, 2024

Hi @arunpatidar 

Yes, the code is called on dialog load. Attached the screenshot and there is a corresponding java servlet mapped to datasource.It's similar to the example code you've shared in the above github link except for getting the resourceresolver from request. I am using resourceresolver from service user

 

arunpatidar
Community Advisor
Community Advisor
November 6, 2024

Hi @divyat3 
Can you please check the servlet status, meybe it is not active.
Please check java imports as well i your servelt, you might be using decommissioned one? example, below will not work in AEMaaCS

import com.adobe.cq.commerce.common.ValueMapDecorator;

 

Please check correct imports in this datasource servlet https://github.com/arunpatidar02/aemaacs-aemlab/blob/master/core/src/main/java/com/community/aemlab/oneweb/core/servlets/ds/ContentTypeDropdownDSServlet.java  

Arun Patidar
EstebanBustamante
Community Advisor and Adobe Champion
EstebanBustamanteCommunity Advisor and Adobe ChampionAccepted solution
Community Advisor and Adobe Champion
November 6, 2024

Hi, 

I think you’re right; the issue may be related to the resourceResolver and the permissions granted to it. Try using "your" resourceResolver solely to gather the items you need to display in the dialog. Try something like this:

try (ResourceResolver resolver = ResourceResolverUtils.getDefaultServiceResourceResolver(resourceResolverFactory)) { ResourceResolver originalResolver = request.getResourceResolver(); request.getSession().setAttribute(DataSource.class.getName(), EmptyDataSource.instance()); List<String> subGroupList = userGroupRetriever.getUsersAndGroups(resolver, parentGroupName, true); List<Resource> fakeResourceList = new ArrayList<>(); for (String subGroup : subGroupList) { ValueMap vm = new ValueMapDecorator(new HashMap<>()); vm.put("value", subGroup.trim().toLowerCase()); vm.put("text", subGroup.trim()); //Note here the resolver changed fakeResourceList.add(new ValueMapResource(originalResolver, new ResourceMetadata(), JcrConstants.NT_UNSTRUCTURED, vm)); }

 

Ultimately, I think the best way to troubleshoot this is by debugging, adding some breakpoints, and seeing what's happening.

 

Hope this helps

 

 

Esteban Bustamante
DivyaT3Author
Level 3
November 7, 2024

Hi @estebanbustamante 

Thank you so much. Adding the original ResourceResolver into the ValueMapResource and not the service user resolver worked. I made slight modification: we do not need session if we are adding the original resolver. Instead of using request.getSession().setAttribute(DataSource.class.getName(), EmptyDataSource.instance());, we can use request.setAttribute(DataSource.class.getName(), EmptyDataSource.instance());

Updated code:

try (ResourceResolver resolver = ResourceResolverUtils.getDefaultServiceResourceResolver(resourceResolverFactory)) {

request.setAttribute(DataSource.class.getName(), EmptyDataSource.instance());

ResourceResolver originalResolver = request.getResourceResolver();

List<String> subGroupList = userGroupRetriever.getUsersAndGroups(resolver, parentGroupName, true);

List<Resource> fakeResourceList = new ArrayList<>();
for (String subGroup : subGroupList) {
ValueMap vm = new ValueMapDecorator(new HashMap<>());
vm.put("value", subGroup.trim().toLowerCase());
vm.put("text", subGroup.trim());
fakeResourceList.add(new ValueMapResource(originalResolver, new ResourceMetadata(), JcrConstants.NT_UNSTRUCTURED, vm));
}

DataSource ds = new SimpleDataSource(fakeResourceList.iterator());

request.setAttribute(DataSource.class.getName(), ds);
} catch (Exception e) {
log.error("Exception occurred {}", ExceptionUtils.getStackTrace(e));
}