0

I am trying to iterate through the list which is stored inside a wrapper list. I want to extract a field value from it and store inside a Set (wrapper again).

Here is my code -


@AuraEnabled(cacheable=true)
public static List<myWrap> getObjectData(
    String accId
    ) {

        List<myWrap> wrapperList = new List<myWrap>();
        try{
            for(Object1__c xyz : [ SELECT Id, Name,
                                   (SELECT Id, Picklist_Names__c FROM Object2__r)
                                    FROM Object1__c
                                    WHERE Account__c =: accId]){

                myWrap wr = new myWrap();
                wr.objName = xyz.Name;
                wr.obj2Data = xyz.Object__r;
//I know I cannot do xyz.Object__r.Picklist_Names__c since it's a list<Object2>
            }
        }
        catch(Exception e){
            system.debug('Inside Catch');
            throw new AuraHandledException('Exception occured');
        }
    return wrapperList;
}
public class myWrap{
    @AuraEnabled
    public String objName{get;set;}
    @AuraEnabled
    public List<Object2__c> obj2Data{get;set;}
    @AuraEnabled
    public Set<String> uniqueNames{get;set;}
}
}

I want to store the Picklist_names__c from obj2Data in the uniqueNames(wrapper Set).

The Why? I am using this returned data from Apex in my LWC JS and showing it inside a lightning-combobox. Right now duplicate values show up on the screen for Picklist_Names__c when I iterate in my LWC JS (using forEach). I am trying to remove the duplicates so I thought of cutting them off in Apex itself before they can be returned to LWC.

I did try to iterate through the wrapper list List but I'm somehow unable to get hold of public List<Object2__c> obj2Data. (keep running into syntax issues) Would really appreciate if anyone can help here or suggest a better approach. Thanks!

1
  • if you want to avoid the inner for loop, you'll need to change your SELECT to make Object2 the target object and sort by its parent Object1__r.Name; But this means conditional logic to know when to build a new wrapper
    – cropredy
    Commented Dec 7, 2022 at 2:00

2 Answers 2

-1

try using below way

@AuraEnabled(cacheable=true)
public static List<myWrap> getObjectData(String accId) {
    List<myWrap> wrapperList = new List<myWrap>();
    try{
        for(Object1__c xyz : [ 
            SELECT Id, Name,
            (SELECT Id, Picklist_Names__c FROM Object2__r)
            FROM Object1__c
            WHERE Account__c =: accId
        ]){
            myWrap wr = new myWrap();
            wr.objName = xyz.Name;
            Set<String> pickListNamesSet = new Set<String>();
            for(Object2__r obj2Record:xyz.Object2__r) {
                pickListNamesSet.add(obj2Record.Picklist_Names__c);
            };
            wr.uniqueNames = pickListNamesSet;
            //I know I cannot do xyz.Object__r.Picklist_Names__c since it's a list<Object2>
        }
    } catch(Exception e){
        system.debug('Inside Catch');
        throw new AuraHandledException('Exception occured');
    }
    return wrapperList;
}
public class myWrap{
    @AuraEnabled
    public String objName{get;set;}
    @AuraEnabled
    public List<Object2__c> obj2Data{get;set;}
    @AuraEnabled
    public Set<String> uniqueNames{get;set;}
}
1
  • Apologies, I should have mentioned, I don't want to go for an inner for loop approach. Commented Dec 6, 2022 at 17:54
-2

I think you can if you know where they are in the set. instead of for each you should use for(Integer i = 0; i< [size of what you need]; i++) like this you can iterate normally and if you need to access to some value of set's value, you also can with xyz.Object__r.Picklist_Names__c[i] let me know if it helpfull !

for example this is my code about a custom sort with wrap:

public List<Account> getAccounts(List<Account> accounts) {
    if(accounts == null) return null;
    List<AccountWrapper> result = new List<AccountWrapper>();
    for (Account acc : accounts) {
        result.add(new AccountWrapper(acc));
    }
    result.sort();
    for(Integer i = 0; i < result.size(); i++) {
        accounts[i] = result[i].acc;
    }
    return accounts;
  }

  public class AccountWrapper implements Comparable {
    public Account acc;

    //constructor
    public AccountWrapper(Account ac) {
      if (ac == null) {
        Exception ex = new NullPointerException();
        ex.setMessage('account argument cant be null');
        throw ex;
      }
      acc = ac;
    }

    //compare 2 accounts based on AnnualRevenue
    public Integer compareTo(Object compareTo) {
      //cast argument to AccountWrapper
      AccountWrapper compareToAcc = (AccountWrapper) compareTo;

      //return 0 if they are equals
      Integer returnValue = 0;
      if(acc.AnnualRevenue == null && compareToAcc.acc.AnnualRevenue == null) return returnValue;
        //here we want to sort by DESC so if we want in ASC just change -1 and 1
      else if(acc.AnnualRevenue == null && compareToAcc.acc.AnnualRevenue != null) returnValue = 1;
      else if (acc.AnnualRevenue != null && compareToAcc.acc.AnnualRevenue == null) returnValue = -1;
      else if(acc.AnnualRevenue > compareToAcc.acc.AnnualRevenue) returnValue = -1;
      else if(acc.AnnualRevenue < compareToAcc.acc.AnnualRevenue) returnValue = 1;
      return returnValue;
    }
  }

I think it would be something like this.

@AuraEnabled(cacheable=true)
    public static List<myWrap> getObjectData(
        String accId
        ) {
    
            List<myWrap> wrapperList = new List<myWrap>();
            Object1__c xyz = [ SELECT Id, Name,
                                       (SELECT Id, Picklist_Names__c FROM Object2__r)
                                        FROM Object1__c
                                        WHERE Account__c =: accId LIMIT 1];
            myWrap wr = new myWrap();
            wr.objName = xyz.Name;

//if all picklist have the same values you can try like this list piclikstValues = new list(); for(Integer i = 0; i < xyz.Object__r.Picklist_Names__c.size(); i++){ piclikstValues.add(xyz.Object__r.Picklist_Names__c[i]); } // suppose wr.picklist exists and you want it // else do another for (here you dont have the inner for just for after another for) wr.picklist = piclikstValues; wrapperList.add(wr); }

            }
            catch(Exception e){
                system.debug('Inside Catch');
                throw new AuraHandledException('Exception occured');
            }
        return wrapperList;
    }
    public class myWrap{
        @AuraEnabled
        public String objName{get;set;}
        @AuraEnabled
        public List<Object2__c> obj2Data{get;set;}
        @AuraEnabled
        public Set<String> uniqueNames{get;set;}
    }
   }
2
  • Using for(Object2__r obj2Record :xyz.Object2__r) as suggested by the other answer is the safest (most correct?) approach here. Trying to directly access child records (and even trying to call xyz.Object2__r.size()) will fail if there are more than ~200 child records for a given parent because Salesforce would try to issue a call to queryMore().
    – Derek F
    Commented Mar 13, 2023 at 12:43
  • Correctness aside, this answer would be improved if you put more work into your example. In isolation, it is not clear where this loop of yours would be placed. I suspect that it would go inside the soql for loop, but OP has stated that they don't want a nested loop. If you're going to suggest something that goes against OP's wishes, then you're responsible for explaining why they should do it your way.
    – Derek F
    Commented Mar 13, 2023 at 12:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .