0

OK, I feel stupid. I've seen other questions from people who got this same error, but none of those scenarios was like mine. So I'm still really confused. My Flow is sending ONE PropertyId to an apex class to retrieve ONE list of related lease records from an external system. My Flow must display some lease info to the user. But I'm getting this "Number of Results does not match number of interviews..." error. I've rewritten the code a dozen different ways. Other posts said to return a list of lists, or a list of objects. still same error. What am I doing wrong here? It must be something really simple and I'm just too inexperienced to see it. Latest version of my code:

public class TPMR_RetrieveData {

public class BuildingDetails {
    @InvocableVariable
    public String PropertyID;
}

public class LeaseInfo {
    @InvocableVariable
    Public String BuildingID;
    @InvocableVariable
    Public String LeaseId;
    @InvocableVariable
    Public String SuiteID;
    @InvocableVariable
    Public String Occupantname;
}
// Retrieve leases by building id
@InvocableMethod(label='GetLeasesByProperty' callout=true) 
    Public static List<List<LeaseInfo>> getLeases(list<BuildingDetails> Details) {
  
   //////get the leases from External system for the building
   http http = new Http();
   HttpRequest req = new HttpRequest();
   TPMR__c MRAuth = TPMR__c.getValues('TPMRConfig');
   req.setEndpoint(MRAuth.endpoint__c + '/-----/api.asp?$api=-----&---id=' + Details.get(0).PropertyId);
   req.setMethod('GET');
   req.setHeader('Content-Type','application/xml'); 

   String username=MRAuth.username__c;
   String password=MRAuth.password__c;
   Blob headerValue = Blob.valueOf(username + ':' + password);
   String authorizationHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
   req.setHeader('Authorization', authorizationHeader);
   HttpResponse response = http.send(req);

     if(response.getStatusCode() <> 200) {
     System.debug(response.getBody());
     }
    
    // Prepare a list to store response

     List<List<LeaseInfo>> Leases = new List<List<LeaseInfo>>();
             
    ///parse the xml response into a map
    Dom.Document doc= response.getBodyDocument();
    Dom.XMLNode lease = doc.getRootElement();
            String BldgId;
            String LeasID;
            String SuitID;
            String OccPname;
            for(Dom.XMLNode child : lease.getChildElements())
            {
                for(Dom.XMLNode child2 : child.getChildElements())
                {       
                    for(Dom.XMLNode child3 : child2.getChildElements()) 
                    {

                        for(Dom.XMLNode child4 : child3.getChildElements()) {
                            if(child4.getName() == 'BuildingID') 
                            {BldgId = child4.getText();}
                             Else
                            if(child4.getName() == 'LeaseID') 
                            {LeasId = child4.getText();}
                            Else
                           if(child4.getName() == 'SuiteID') 
                            {SuitId = child4.getText();}
                           Else
                           if(child4.getName() == 'OccupantName') 
                            {OccPname = child4.getText();} 
                               If (BldgID != Null) {
                               LeaseInfo l = new LeaseInfo();
                               l.BuildingId = BldgId;
                               l.LeaseId = LeasId;
                               l.SuiteId = SuitID;
                               l.OccupantName = OccpName;
                               list<LeaseInfo> li = new list<LeaseInfo>();
                               li.add(l);
                               Leases.add(li);
                        } 
                      }

                    }
                }
            }        
    // return MR lease list

    Return Leases;
    }

}

1 Answer 1

0
Leases.add(li);

You're adding li once for every lease in the list. This results in your return value (leases) having too many or too few elements. li should be near the top, and added once:

List<List<LeaseInfo>> Leases = new List<List<LeaseInfo>>();
List<LeaseInfo> li = new List<LeaseInfo>();
leases.add(li);
Dom.Document doc= response.getBodyDocument();
Dom.XMLNode lease = doc.getRootElement();
String BldgId;
String LeasID;
String SuitID;
String OccPname;
for(Dom.XMLNode child : lease.getChildElements())
{
  // rest of code, but remember to remove leases.add(li) down below
}

Note that this code is not bulkified. You should consider using a proper loop over each input from Details, otherwise your flow may break in some cases (e.g. when using a Scheduled Flow).

2
  • Thank you. This worked. Although, I still don't understand exactly why it worked.
    – april
    Oct 11, 2023 at 13:28
  • @april See InvocableMethod and Flow Bulkification. In summary, though, Apex Actions assume that more than one flow may be processing at once, e.g. from time delayed flows. This is why your flow accepts a list and returns a list of a list. The return value will be mapped to a collection variable for potentially multiple interviews.
    – sfdcfox
    Oct 11, 2023 at 14:26

You must log in to answer this question.

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