0

I have the below piece of code.

------------------Apex class----------------

public static String retrieveLayoutMetadata ( String strLayoutConfig ) {
    System.debug(' strLayoutConfig      :     ' + strLayoutConfig);
    Map<String, Object> mapLayoutResult = new Map<String, Object>();
    List<LayoutWrapper.LayoutSection> lstLayoutSections = new List<LayoutWrapper.LayoutSection>();
    setLayoutFieldApi = new Set<String>();

    LayoutConfigWrapper layoutConfig = (LayoutConfigWrapper) JSON.deserialize(strLayoutConfig, LayoutConfigWrapper.class);

    if(layoutConfig != null) {

        // Get the object schema and all its field map --
        descResult = Schema.describeSObjects( new String[]{ layoutConfig.objectApi } );
        mapFields = descResult[0].fields.getMap();
        isAllReadOnlyFields = true;

        // List fullnames of components we want to retrieve
        List<String> lstComponentName = new List<String>{ layoutConfig.objectApi + '-' + layoutConfig.layout };
    
        // Retrieve component "Error Block" 
        List<Metadata.Metadata> lstComponents =         
        Metadata.Operations.retrieve(  Metadata.MetadataType.Layout, lstComponentName);
        Metadata.Layout layoutMeta = (Metadata.Layout) lstComponents.get(0);
    
        // Prepare layout fields of retrieved component
        for(Metadata.LayoutSection layoutSec : layoutMeta.layoutSections) {
            
            List<LayoutWrapper.LayoutField> lstLayoutFields = new List<LayoutWrapper.LayoutField>();

            for(Metadata.LayoutColumn layoutCol : layoutSec.layoutColumns) {
                if(layoutCol.layoutItems != null) {
                    lstLayoutFields.addAll( prepareColumn(layoutCol, layoutConfig) );
                }
            }

            if(!lstLayoutFields.isEmpty()) {
                lstLayoutSections.add( new LayoutWrapper.LayoutSection(layoutSec.label, lstLayoutFields, true));
            }}
        
        if(!lstLayoutSections.isEmpty()) {
            LayoutWrapper layoutWrap = new LayoutWrapper(lstLayoutSections, isAllReadOnlyFields);
            mapLayoutResult.put('layoutWrapper', layoutWrap);
        }}
   
    mapLayoutResult.put('layoutFields', setLayoutFieldApi);
    System.debug(' mapLayoutResult      :     ' + mapLayoutResult);
    return JSON.serialize(mapLayoutResult);
}

And this is test class :

static void testRetrieveLayoutMetadata() {

    Test.startTest();
    Map<String, Object> mapResult;
    String strLayoutConfig = '{ "objectApi": "Applicant__c", "layout": "Sales Data Entry KYC Details", "hiddenRequiredFields": ["Name"] }';
    System.debug('strLayoutConfig'+strLayoutConfig);
    string strResult = SalesDataEntryController.retrieveLayoutMetadata(strLayoutConfig);      
    System.debug('strResult'+strResult);
    mapResult = (Map<String, Object>) JSON.deserializeUntyped(strResult);     
    System.debug('strResult'+strResult);
    System.assert(mapResult != null && mapResult.get('layoutFields') != null, 'Error - Something went wrong.');        
    Test.stopTest();
}

Can somebody help you with this error "List index out of bound" Thank you

7
  • 1
  • @glls tried this already ..dint worked.. if you can post a piece of code for the same apex will be a great help. Mar 24 '21 at 18:10
  • 1
    Please edit your post to specify where the error takes place. Generally, this is an issue (like NullPointerException) that you can solve by looking at your code and the data it is processing. You're currently trying to access an empty list.
    – David Reed
    Mar 24 '21 at 18:11
  • @DavidReed .thanks updated Mar 24 '21 at 18:14
  • @CasparHarmer almost there. Can you please help me not sure where I am going wrong? Mar 24 '21 at 18:20
1

The only clear explanation that I see is that the name of the metadata component your unit test is trying to retrieve is incorrect. The behavior of that API is to return an empty list if no components are found matching the given list of names.

This unit test succeeds in my dev org, showing that metadata retrieves are quite legal in a unit test:

@isTest
public class TestQ337774 {
    @isTest
    public static void runTest() {
        List<Metadata.Metadata> lstComponents = Metadata.Operations.retrieve(
            Metadata.MetadataType.Layout, new List<String>{'Account-Account Layout'}
        );
        
        System.assertEquals(1, lstComponents.size());
        Metadata.Layout layoutMeta = (Metadata.Layout) lstComponents.get(0);
        
        System.assertNotEquals(null, layoutMeta);

    }
}

It also works fine with custom object layouts.

The only conclusions I can see is that either:

  • there is no layout called Applicant__c-Sales Data Entry KYC Details in your org;
  • or there's a bug I'm not spotting in your JSON code resulting in you generating an incorrect layout name, which debug logs should be able to show you if that's the case.
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.