1

I'm querying via the REST API (in Apex, because I'm calling another org, amongst other reasons) and using a wacky recursive algorithm on the first returned record to parse out the field names. And no, for my purposes, I cannot parse the fields names from the query string, for a multitude of reasons.

Sample query

SELECT Name, (SELECT Firstname, Account.Id From Contacts) FROM Account LIMIT 2

My result when all is well. This is what I'm looking for.

"fieldToObjectWrapper": {
    "null": {
        "Name": "Account"
    }, 
    "Contacts": {
        "Contact.Account.Id": "Account", 
        "Contacts.FirstName": "Contact"
    }
}

My problem comes when the first returned record has no child records. The child node doesn't exist, so I can't parse the fields.

QueryResult with a "good" first record

{
  "attributes": {
    "url": "/services/data/v44.0/sobjects/Account/0016100000W5K09AAF", 
    "type": "Account"
  }, 
  "Name": "Company A", 
  "Contacts": {
    "totalSize": 1, 
    "done": true, 
    "records": [
      {
        "FirstName": "Whoever", 
        "attributes": {
          "url": "/services/data/v44.0/sobjects/Contact/0036100001aVoyOAAS", 
          "type": "Contact"
        }, 
        "Account": {
          "attributes": {
            "url": "/services/data/v44.0/sobjects/Account/0016100000W5K09AAF", 
            "type": "Account"
          }, 
          "Id": "0016100000W5K09AAF"
        }
      }
    ]
  }
},
{
  "attributes": {
    "url": "/services/data/v44.0/sobjects/Account/0016100000W5K0AAAV", 
    "type": "Account"
  }, 
  "Name": "Company B"
}

But imagine if Company B came first. No Contacts so no fields to parse.

It dawned on me that the Workbench must be doing something similar to display its query results so I dug into the open source code. My PHP is... lacking... but from what I can tell, they're actually doing the same thing (which made me feel good about myself). They're taking the first record from the results and parsing out the names.

https://github.com/forceworkbench/forceworkbench/blob/master/workbench/async/QueryFutureTask.php

On line 237, in createQueryResultTable, they're passing $records[0] into getQueryResultHeaders, which then calls itself recursively as it loops through the fields.

But in the Workbench, it works. (Maybe that's why they call it the Workbench...) They get the field names regardless of whether the first record contains child records or not.

enter image description here

How do they do that? What am I missing? Is there another way?

Thanks very much!

UPDATE Question answered in the comments. Thanks to all for playing!

  • In subquery, we already provided the fields name (Firstname, Account.Id). Can't we create table header using these fields? – Pragati Jain Oct 21 '18 at 16:05
  • Can you show us an actual example from the workbench? What feature are you talking about in Workbench? As far as I can tell, it doesn't show anything if there are no child records--each row in the query result is rendered independently. – sfdcfox Oct 21 '18 at 16:28
  • @sfdcfox I've added a Workbench screenshot. I know each result is rendered independently, but surely they only grab the the headers once? Hmm. Then again... Okay. So they're doing it while they render each row.. rather than what I'm doing.. which is getting all my headers at the start. Maybe that's it. – David Oct 21 '18 at 16:41
  • @PragatiJain As I mention in my opening, there are many reasons (that I won't get into) that I won't get the headers from the query itself, but thank you. – David Oct 21 '18 at 16:42
  • 1
    @David Precisely that. They literally dump a new table inside the table cell of the parent. There's no special magic going on here. – sfdcfox Oct 21 '18 at 16:42

Your Answer

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

Browse other questions tagged or ask your own question.