Get sObject name from salesforce Id

  • 1
  • Question
  • Updated 8 months ago
  • Answered
I am trying to build ONE page to display and add notes/attachments and also display the object history which can be used across all objects through a page include.

I am thinking the page can take the salesforce id of the record and based on the id, I can determine which salesforce object it is and then create the model using javascript.

My question is how can I can determine the sObject based on the id? I know how to do it in apex but it would be great if I could somehow achieve it using Skuid.
Photo of Ashwat

Ashwat

  • 768 Points 500 badge 2x thumb

Posted 1 year ago

  • 1
Photo of Zach McElrath

Zach McElrath, Employee

  • 49,056 Points 20k badge 2x thumb
To SObject based on an Id, you will need to build up a mapping of SObject Key Prefixes (e.g. 001, 500, 006) to their associated SObject Names (e.g. Account, Case, Opportunity, respectively).

One trick to creating this map is to piggyback on the fact that Skuid pulls down this metadata for polymorphic fields, such as "WhatId" on Task or "ParentId" on Attachment / Note. So if you have a Model on Attachment / Note / Task and pull in just the WhatId / ParentId field, and don't query for any records at all, you can inspect the field metadata from JavaScript and construct the map of Key Prefixes to SObject Names.

Then you can add a Snippet that simply takes a row's record Id / Parent Id, whatever Id you care about and then check the first 3 digits of the Id against your map.

Here is the XML for a simple page that does this. Hopefully this steers you in the right direction for your use case.






<skuidpage unsavedchangeswarning="yes" personalizationmode="server" useviewportmeta="true" showsidebar="true" showheader="true" tabtooverride="Note">
    <models>
        <model id="ObjectMetadata" limit="" query="false" createrowifnonefound="false" datasource="salesforce" sobject="Attachment" type="">
            <fields>
                <field id="ParentId"/>
            </fields>
            <conditions/>
            <actions/>
        </model>
        <model id="Attachments" limit="20" query="true" createrowifnonefound="false" datasource="salesforce" type="" sobject="Attachment">
            <fields>
                <field id="Id"/>
                <field id="Name"/>
                <field id="ParentId"/>
                <field id="Parent.Name"/>
            </fields>
            <conditions/>
            <actions/>
        </model>
    </models>
    <components>
        <pagetitle model="ObjectMetadata" uniqueid="sk-12SIg2-76">
            <maintitle>
                <template>{{Model.labelPlural}}</template>
            </maintitle>
            <subtitle>
                <template>Home</template>
            </subtitle>
            <actions/>
        </pagetitle>
        <skootable showconditions="true" showsavecancel="false" showerrorsinline="true" searchmethod="server" searchbox="true" showexportbuttons="false" pagesize="10" alwaysresetpagination="false" createrecords="false" model="Attachments" buttonposition="" mode="readonly" allowcolumnreordering="true" responsive="true" uniqueid="sk-12U5en-867">
            <fields>
                <field id="Id" hideable="true" uniqueid="fi-12U6wH-881"/>
                <field id="Name" hideable="true" uniqueid="fi-12U6wH-882"/>
                <field id="ParentId" hideable="true" uniqueid="fi-12U6wI-883"/>
            </fields>
            <rowactions>
                <action type="multi" label="Get SObject Type from Id" icon="sk-icon-magic">
                    <actions>
                        <action type="custom" snippet="getSObjectTypeFromParentId"/>
                    </actions>
                </action>
            </rowactions>
            <massactions usefirstitemasdefault="true"/>
            <views>
                <view type="standard"/>
            </views>
        </skootable>
    </components>
    <resources>
        <labels/>
        <css/>
        <javascript>
            <jsitem location="inline" name="determine object type from row id" cachelocation="false" url="">(function(skuid){
var $ = skuid.$;
var objectTypesByKeyPrefix;

skuid.snippet.register("getSObjectTypeFromParentId", function(params){ 
   var row = params.item ? params.item.row : params.row;
   var parentId = row.ParentId;
   console.log("ParentId: " + parentId);
   if (!objectTypesByKeyPrefix) generateCache();
   var objectType = objectTypesByKeyPrefix[parentId.substring(0,3)] || "Unknown Key Prefix: " + parentId.substring(0,3);
   console.log("Parent Object Type is: " + objectType);
});

function generateCache() {
   objectTypesByKeyPrefix = {}; 
   skuid.$M("ObjectMetadata").getField("ParentId").referenceTo.forEach(function(relatedObject){
       objectTypesByKeyPrefix[relatedObject.keyPrefix] = relatedObject.objectName; 
   });
}


})(skuid);</jsitem>
        </javascript>
        <actionsequences uniqueid="sk-12SK99-105"/>
    </resources>
    <styles>
        <styleitem type="background" bgtype="none"/>
    </styles>
</skuidpage>
Photo of Ashwat

Ashwat

  • 768 Points 500 badge 2x thumb
That is a work of art! That is exactly what I needed.

Thanks Zach!
Photo of Ashwat

Ashwat

  • 768 Points 500 badge 2x thumb
@Zach - did anything change with a recent skuid upgrade that would make the above solution to not work?

Based on what you had suggested earlier in this post, i created a skuid page which displays notes and attachments and have been using it as a page include along all the detail pages of all my objects. This morning I noticed that the page is bugging out and on page load when this runs

function buildsObjectMap(){
       objectTypesByKeyPrefix = {}; 
       skuid.$M("rl_ObjectMetadata").getField("ParentId").referenceTo.forEach(function(relatedObject){
           objectTypesByKeyPrefix[relatedObject.keyPrefix] = relatedObject.objectName;
       });
    }

Getting this error - Uncaught TypeError: Cannot read property 'referenceTo' of undefined

I tried changing the object behind the rl_ObjectMetaData model from attachment to task, and changed the ParentId in the javascript to whatId - still got the same error.

We upgraded our sandboxes to 11.1.6 earlier today, so I thought of checking out production which is on 11.0.3 and this page works fine there. Could you please help me with this?
Photo of Ashwat

Ashwat

  • 768 Points 500 badge 2x thumb
Did some more research this morning and it feels like $model.getField is not working correctly? This is the snippet that executes on page load

(function(skuid){
    var $ = skuid.$;
    var objectTypesByKeyPrefix;
    $(function(){
        $.blockUI({message: 'Please wait...', timeout: 2000});
        if (!objectTypesByKeyPrefix) buildsObjectMap();
        var attachmentModel = skuid.$M('rl_attachments');
        var recordId = attachmentModel.conditions[0].value;
        if (recordId !== undefined){
            var parentModel = skuid.model.getModel('rl_GenericModel');
            var parentModelIdCondition = parentModel.getConditionByName('parentModelId') ;
            if (parentModel.objectName !== objectTypesByKeyPrefix[recordId.substring(0,3)]) {
                parentModel.objectName = objectTypesByKeyPrefix[recordId.substring(0,3)];
            }
            parentModel.setCondition(parentModelIdCondition,recordId);
            parentModel.updateData();
        }
    });
    
    function buildsObjectMap(){
       objectTypesByKeyPrefix = {}; 
       skuid.$M("rl_ObjectMetadata").getField("ParentId").referenceTo.forEach(function(relatedObject){
           objectTypesByKeyPrefix[relatedObject.keyPrefix] = relatedObject.objectName;
       });
    }

})(skuid);

I was debugging and I found out that skuid.$M("rl_ObjectMetadata").getField("ParentId") was returning a null. But when I execute the same thing in the chrome console, it works fine. I tried to replace skuid.$M("rl_ObjectMetadata").getField("ParentId") with skuid.$M("rl_ObjectMetadata").fields[0] and this seemed to work fine, but this time skuid.$M("rl_ObjectMetadata").fields[0].referenceTo returned null and again it worked in the chrome console. 

Also as I mentioned in my previous post, all of this is happening in 11.1.6. The production org which is on 11.0.3 is working normally without any issues with the exact same code.