function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Connor CainConnor Cain 

Apex Code: get Meta data for all Fields in an Object

I am building an Apex project that will display a current Data Dictionary of our Org for Specific objects. I am also using this project to learn how to program in Apex and this is my first experience. I have build out a working model that gets the Api Name, label, and Datatype from the code below:
---------------------------------------------------------------------------------------------------------------
public static List<DataPoint> getAccountList(){
        List<DataPoint> myList = new List<DataPoint>();
        List<FieldDefinition> Query1 = new List<FieldDefinition>([Select DeveloperName, Label, Datatype From FieldDefinition where EntityDefinition.QualifiedApiName = 'Account' ORDER BY DeveloperName limit 1000]);
        For(Integer i = 0; i < Query1.Size(); i++){
            Try{
                String Q1 = String.valueOf(Query1[i]);
                DataPoint dp = new DataPoint(Q1.substringBetween('DeveloperName=',', Label='),
                                             Q1.substringBetween('Label=',', DataType='),
                                             Q1.substringBetween('DataType=',', EntityDefinitionId='),
                                             '', '', '');  //just a stand in 
               //Query to get Inhelptext, Description, and Created Date 
               //Add Inhelptext, Description, and Created Date to dp where the DeveloperName matches 
                myList.add(dp); 
            }Catch(System.NullPointerException e){
                 myList.add(new DataPoint('','','','','',''));
            }
        }
        Return myList;
    }
---------------------------------------------------------------------------------------------------------------
**DataPoint is just a custom class I built to hold the values and display them on the VisualForce Page. 
Now I would like to query InhelpText, Description, and maybe Created Date from CustomFields but I run into errors like [invalid: Customfield] because CustomField needs the Tooling API to be able to query into this.
So for my Question, How can I get the Description, InlineHelpText, to be able to put into these lists and complete the Data Dictionary? Is there a Work around to allow Tooling API or should I be taking a different approach? What can I add to my code above to make it work?
 
Alain CabonAlain Cabon
Hi,

The tooling API is requested via Rest calls (HttpRequest) in Apex.

But it is easier to use the dynamic field tokens from the apex namespace Schema.
 
String selectedObject = Account.sObjectType.getDescribe().getName();
selectedObject = 'MyCustomObject__c';
system.debug(selectedObject);
Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
Schema.SObjectType objectSchema = schemaMap.get(selectedObject);
Map<String, Schema.SObjectField> fieldMap = objectSchema.getDescribe().fields.getMap();
for (String fieldName: fieldMap.keySet()){  
       system.debug('field name:' +  fieldName + ' label:' + fieldMap.get(fieldName).getDescribe().getLabel() + 
                   ' type:' +  fieldMap.get(fieldName).getDescribe().getType());
}


https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_namespace_Schema.htm

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dynamic_field_tokens.htm

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_sobject_describe.htm#apex_Schema_DescribeSObjectResult_fields
 
Alain CabonAlain Cabon
DeepField:  if you want to call the tooling API in Apex nevertheless here is a great sample of code:

https://github.com/regularcoder/deepfield/blob/master/classes/DeepFieldController.cls
Connor CainConnor Cain
So i tried option 2 by copying DeepField because it would be easiest for printing on the visual force page. and I got these errors:
-------------
From    Subject    Received    Size    Categories    
ApexApplication    Sandbox: Developer script exception from *Company*  : DataDictionaryApexCode : Unauthorized endpoint, please check Setup->Security->Remote site settings. endpoint = https://c.cs#.visual.force.com/services/data/v44.0/tooling/query/?q=SELECT+description...etc   

and after adding a Remote site setting

Too many callouts: 101    
------------

any idea why these failed?
Alain CabonAlain Cabon
Hi,

The "too many callouts : 101"  How many objects did you select?

It is almost impossible to overcome the governor limits with synchronous calls if you select too many objects or fields (algorithm too simple).

DeepField is great because it is short, sufficient and solved the problem of querying with tooling requests from Apex but a so short code cannot overcome the governor limits (too simple).

You need many asynchronous requests and in Apex the asynchronous parallel treatments are possible but your code will be much more complicated than Deepfield.
As soon as you use asynchronous calls, you can make thousands of sequential requests with some of them running in parallel but the problem is to wait and collect all the responses of these asynchronous treatments.

Promises And Apex: Easy, Robust Async Code Execution
The Promise pattern has a long history in Javascript and is now available in Apex! Promises give developers flow control over async code, making it easier to debug and maintain. This enables the development of monadic 'chains' of smaller tasks. After this session you'll be able to define the Promise pattern, define monad, use queueable Apex, and use the Promises Framework to create and use Promises in Apex.

https://www.salesforce.com/video/1384499/
Alain CabonAlain Cabon
DeepField is great because it is short, sufficient and solved the problem of querying with tooling requests from Apex but a so short code cannot resolve the problem of the governor limits (too simple).