AEM Multi-fields not returning from Sling Model | Community
Skip to main content
August 26, 2021
Solved

AEM Multi-fields not returning from Sling Model

  • August 26, 2021
  • 3 replies
  • 6211 views

Hello AEM Heads!

 

I have been wracking my brain on this for well over a week now and figured I'd reach out and try to see what I am doing wrong. I have set-up a multi-field in my cq:dialog for this component and, as you can see, they are being are stored correctly in crxdelite, but when I have tried to pull them out and into the HTML, I am not seeing them being displayed. You can see the code below, where it is being called, the Model I have created, and how it's being stored. I did check the logs and see that I was receiving an Error from the Model and that the multi-field size was 0, however, since I am getting the "cards" item in my model, I'm not sure why it's not counting those?

 

Just not really sure what to do as I've tried a lot of tweaking to no luck. Any insight would be greatly appreciated!!

 

Edit: Removing third party code

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 Umesh_Thakur

First of all you should not make your sling model adaptables to SlingHttpServletRequest specially to get value from multifiled. then you made a mistake by trying to directly inject your resource for multifield. These are some mistake you have done prima-facie.

Please go thru the below article which fits 100% in your requirement.

https://helpx.adobe.com/experience-manager/using/aem64_htl_repeat_slingmodel.html

Just see the sling model 

 

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
 
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
import org.apache.sling.settings.SlingSettingsService;
 
@Model(adaptables = Resource.class)
public class Multifield {
 
 // Inject the products node under the current node
 @586265
 @7392697
 public Resource products;
 
 // No need of a post construct as we don't have anything to modify after the
 // model is constructed
}
 

and HTL code like

<div
    data-sly-use.multiItems="aem.community.mf.core.models.Multifield">
    <div data-sly-list.head="${multiItems.products.listChildren}">
 
 
  <div style="height:250px;"><img src=${head.pathbr} height=200 width=270 style="padding:4px"/><h2>${head.product}</h2>
                             <p>${head.desc}</p>
 
                             </div>
                             <hr>
 
   </div>
</div>

 

Hope this will help.

Umesh Thakur

3 replies

Umesh_Thakur
Community Advisor
Umesh_ThakurCommunity AdvisorAccepted solution
Community Advisor
August 26, 2021

First of all you should not make your sling model adaptables to SlingHttpServletRequest specially to get value from multifiled. then you made a mistake by trying to directly inject your resource for multifield. These are some mistake you have done prima-facie.

Please go thru the below article which fits 100% in your requirement.

https://helpx.adobe.com/experience-manager/using/aem64_htl_repeat_slingmodel.html

Just see the sling model 

 

import javax.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
 
import org.apache.sling.api.resource.Resource;
import org.apache.sling.models.annotations.Default;
import org.apache.sling.models.annotations.Model;
import org.apache.sling.models.annotations.Optional;
import org.apache.sling.settings.SlingSettingsService;
 
@Model(adaptables = Resource.class)
public class Multifield {
 
 // Inject the products node under the current node
 @586265
 @7392697
 public Resource products;
 
 // No need of a post construct as we don't have anything to modify after the
 // model is constructed
}
 

and HTL code like

<div
    data-sly-use.multiItems="aem.community.mf.core.models.Multifield">
    <div data-sly-list.head="${multiItems.products.listChildren}">
 
 
  <div style="height:250px;"><img src=${head.pathbr} height=200 width=270 style="padding:4px"/><h2>${head.product}</h2>
                             <p>${head.desc}</p>
 
                             </div>
                             <hr>
 
   </div>
</div>

 

Hope this will help.

Umesh Thakur

August 26, 2021

Hello @umesh_thakur !

 

Thank you all for your responses. I have gone through all the responses and tested each one, however, I am stuck with an error now being output. As you can see, my code has been updated to Inject the cards as a Resource, I've removed the SlingHttpServletRequest, and I have tested by removing my getHeader function and even making a very simple model that only returns the cards, but this my error:

 

Any ideas??

VeenaVikraman
Community Advisor
Community Advisor
August 26, 2021

@socialtaylor Your code looks good to me now. If everything goes well, this has to execute. There can be few weird situations. Something like your jar bundles are not updated. Just for a cross verification, remove the bundle package completely from your system/console and reinstall and check if this resolves your issue. Adding some references below for this kind of issue. 

 

https://github.com/adobe/aem-component-generator/issues/19#issuecomment-559168608

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/no-use-provider-could-resolve-identifier/td-p/202841 

https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/getting-error-msg-no-use-provider-could-resolve-identifier-when/m-p/188562  ( this might not be valid in your case)

Kiran_Vedantam
Community Advisor
Community Advisor
August 26, 2021

Hi @socialtaylor,

 

In the model, you are adapting it with SlingHttpRequest and trying to inject the multi field resource which will not work.

Try adding the Resource as one of the adatables (along with the request) or try this

@Inject @Via("resource")

Resource componentResource;

 

It should work.

Relevant URL's:

  1. https://sling.apache.org/documentation/bundles/models.html
  2. https://stackoverflow.com/questions/54454534/what-is-the-significance-of-declaring-a-sling-model-as-adaptables-resource-cl

Hope this helps.

Thanks,

Kiran Vedantam.

VeenaVikraman
Community Advisor
Community Advisor
August 26, 2021

@socialtaylor There are few minor adjustments you have to do to your logic to get this work . Find below the sample model I did to just implement the very basic of your logic

 

1. First point you have to understand is the naming conventions. Since your component's multifield has name cards , as you can see in your node structure , each items starting from item0 , item1,.... will get added to a node/ resource by name "cards" . So basically you have to inject the resource which has the name as "cards" .

Below image explains the nodes as per my component structure

 

 In your code, at line 27,  you are trying to inject a resource componentResource . I am not sure from where you are referring that name. If we have to go by the names you have given and the nodes which are created , you should have been injecting the Resource as "cards"

2. Now as have I explained in another forum post https://experienceleaguecommunities.adobe.com/t5/adobe-experience-manager/usage-of-via-in-sling-models/td-p/283719 you have to use @Via("resource") to get any Resources in your model if you are adapting your model using SlingHttpServletRequest.class . 


But I think , since you don't need any request object in your model , you can better avoid using SlingHttpServletRequest.class and use only Resource.class ( Request is reccomended only when you need to use any object which Resource cannot provide) So may be you can rewrite your adaptable as something like below

If you notice , in this case , you don't have to Inject it via resource , because your model is adapted via Resource.


Also , I think the logic you have written in the post construct is not needed. It can be simplified and done directly in the HTL as below 

@Inject
@Via("resource")

Resource cards;

public Resource getCards() {

return cards;
}


Return your cards resource via a getCards() method in the Model and do the below in the HTL

<div
data-sly-use.model="com.learn.practice.aem.core.models.MultifieldSampleModel">
<div data-sly-list.children="${model.cards.listChildren}">
${children.headerText}

${children.headerImage}
${children.content}
</div>
</div>

Depending on your requirement and FE rendering play around with this values in the HTL.

   Hope this helps. I tried to explain it the best I could, but still if you have any questions please let me know. Hope you get it resolved asap. Next time  don't wait for a week , but an extra eye might help to catch the issues 🙂 Always feel free to come back to forum if you face any issues 🤗 

Veena ✌