Expand my Community achievements bar.

How implement a multifield component in AEM React SPA ?

Avatar

Level 3

Hi Team, 

Trying to implement a multified component in AEM React SPA. But not sure how to pass the json data for each item being generated in multifield. Could anyone please suggest me the best and possible method for this one with an example ? Preferably java sling model for the same. 

7 Replies

Avatar

Community Advisor

Hi @akashkriz005 
Please follow the below steps
1.Create the Sling Model
2.Create the Sightly (HTML) file
3.Create the React Component
4.Create the React Component
5.Display the Multifield Component in SPA
you might need to adjust the Sling Model and React component accordingly.
Also, make sure to replace /content/multifield-component-path with the actual path to your multifield.

Thanks



Avatar

Level 3

Hi @Raja_Reddy  

Thanks for the info. But in case of SPA we are passing json data to UI team for mapping it with react component right? So do we need to write any sightly ? 
And also if you have any Sling model reference to pass multifield data as a json , could you please mention ? 

Avatar

Community Advisor

Hi @akashkriz005 
a Single Page Application (SPA) where you pass JSON data to the UI team for mapping with React components, you typically don't need to use Sightly (HTL) directly. Instead, you use Sling models on the server side to convert AEM content into a JSON format that can be consumed by your SPA.

1.Define Sling Models
2.Implement the Sling Models
3.Serialize the Model to JSON
4.Use the JSON in the SPA
With this setup, you can access the JSON data in your SPA by making a request to the appropriate URL, which corresponds to the Sling resource that has the Multifield Model applied.

Thanks.



Avatar

Level 3

Thanks @Raja_Reddy for the info. 

Do you have any valid reference I can look up into ? Especially sling models

Avatar

Community Advisor

In AEM React SPA, you can map AEM components to SPA components. The JSON content exposed by an AEM component can be automatically injected into a React component as....

For example here is a sample Sling Model for a multifield component:

@Model(adaptables = Resource.class)
public interface MyComponentModel {

    @Inject
    List<MyItem> getItems();

    @Model(adaptables = Resource.class)
    interface MyItem {
        @Inject
        String getTitle();

        @Inject
        String getDescription();
    }
}

In this code, MyComponentModel is the Sling Model for your component, and MyItem is the Sling Model for each item in the multifield. The getItems method returns a list of MyItem objects, each representing an item in the multifield.

You can then use the ModelManager in your React component to access the data:

import {ModelManager} from '@adobe/cq-spa-page-model-manager';

// ...

ModelManager.getData("/content/my-page.model.json").then((model) => {
    let myComponentData = model["my-component"]["items"];
    // Use myComponentData in your component
});

In this code, ModelManager.getData fetches the model data for the page, and model["my-component"]["i....

For more detailed examples and information, here are some references:

 

Avatar

Administrator

@akashkriz005 Did you find the suggestions from users helpful? Please let us know if more information is required. Otherwise, please mark the answer as correct for posterity. If you have found out solution yourself, please share it with the community.



Kautuk Sahni

Avatar

Level 3

Hi Everyone , 

I was trying all the possible way to implement this , but still I'm not able to proceed further. Mentioning the issue on detail. 

This my Java sling model code written for multifield. 

import java.util.List;

 

import javax.inject.Inject;

 

import org.apache.sling.api.SlingHttpServletRequest;

import org.apache.sling.api.resource.Resource;

import org.apache.sling.models.annotations.DefaultInjectionStrategy;

import org.apache.sling.models.annotations.Exporter;

import org.apache.sling.models.annotations.Model;

import org.apache.sling.models.annotations.Optional;

 

 

import com.adobe.cq.export.json.ComponentExporter;

import com.adobe.cq.export.json.ExporterConstants;

 

@Model(adaptables = SlingHttpServletRequest.class, adapters = ComponentExporter.class, resourceType = BannerModel.RESOURCE_TYPE, defaultInjectionStrategy = DefaultInjectionStrategy.OPTIONAL)

 

@exporter( // Exporter annotation that serializes the model as JSON

name = ExporterConstants.SLING_MODEL_EXPORTER_NAME, extensions = ExporterConstants.SLING_MODEL_EXTENSION)

 

public class BannerModel implements ComponentExporter {

 

 

protected static final String RESOURCE_TYPE = "sampleproject/components/banner";

 

@inject

@Optional

private List<MultifieldItem> bannerlist;

 

@Override

public String getExportedType() {

 

return null;

}

 

public static String getResourceType() {

return RESOURCE_TYPE;

}

 

public List<MultifieldItem> getBannerlist() {

return bannerlist;

}

 

 

public class MultifieldItem {

 

@inject

@Optional

private String bannertext;

 

@inject

@Optional

private String bannericon;

 

public String getBannertext() {

return bannertext;

}

 

public String getBannericon() {

return bannericon;

}

 

}

 

}

After building the code , Even the component itself is not getting loaded on the page. But if I remove the List concept , Component is getting loaded. Could someone please suggest if any wrong approach I'm following here ?