I need to get the type (or data type) of a field (like if it is a date or integer for example) in apex.
I only have the name (api) of the object and the name of the field.
How can I do that ?
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It only takes a minute to sign up.
Sign up to join this communityI need to get the type (or data type) of a field (like if it is a date or integer for example) in apex.
I only have the name (api) of the object and the name of the field.
How can I do that ?
The other two are right that you can use Schema.getGlobalDescribe()
, but it is notoriously slow. Make sure that you either cache the global describe into a static variable so that you only call Schema.getGlobalDescribe()
once per transaction, or consider the method from this question: Why is Schema.describeSObjects(types) Slower Than Schema.getGlobalDescribe()?
Which would look like this for your case:
String objectName = 'Account';
String fieldName = 'Name';
SObjectType r = ((SObject)(Type.forName('Schema.'+objectName).newInstance())).getSObjectType();
DescribeSObjectResult d = r.getDescribe();
System.debug(d.fields
.getMap()
.get(fieldName)
.getDescribe()
.getType());
depends on what you want to get: SOAPType or DisplayType
String objectName = 'Opportunity';
String fieldName = 'AccountId';
Schema.DisplayType f = Schema.getGlobalDescribe() // or Schema.SOAPType
.get(objectName)
.getDescribe()
.fields
.getMap()
.get(fieldName)
.getDescribe()
.getType(); // or getSOAPType()
System.debug(f);
This is a bit irritating in SF (from my point of view). But you can do it like this:
String objType=’YourObject’;
Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
Schema.SObjectType leadSchema = schemaMap.get(objType);
Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap();
for (String fieldName: fieldMap.keySet()) {
Schema.DisplayType fielddataType = fieldMap.get(fieldName).getDescribe().getType();
}
Important to note that while the other answers here will do what you're looking to do, there is a subtle gotcha I discovered while making a method to grab any phone numbers off of a record on a standard controller:
public String getSObjectPhoneFields() {
SObject sObj = scon.getRecord();
Schema.DescribeSObjectResult objectDescribe = sObj.getSObjectType().getDescribe();
Map<String, Schema.SObjectField> fields = objectDescribe.fields.getMap();
Map<String, Object> result = new Map<String, Object>();
for(String fieldName : fields.keySet()) {
Schema.SObjectField field = fields.get(fieldName);
Schema.DescribeFieldResult fieldDescribe = field.getDescribe();
if(fieldDescribe.getType() == Schema.DisplayType.Phone) {
result.put(fieldDescribe.getLabel(), sObj.get(field));
}
}
return JSON.Serialize(result);
}
As it turns out, Schema.DisplayType is not the same as the DATA TYPE column in the object manager. This manifested as (in my case) the Fax number on the Contact type being handed in as a phone number, despite it's DATA TYPE being Fax. This is because a Fax is displayed (see: Schema.DisplayType) as a phone number, despite it being a different data type.
I wasn't able to find how to access the data type. It doesn't appear to be available through the API.
Even more simple now!
public String getFieldDataType(String objectName, String fieldName){
return [SELECT DataType
FROM FieldDefinition
WHERE EntityDefinitionId=:objectName AND QualifiedApiName=:fieldName
LIMIT 1].DataType;
}