0

I have a Lightning component with a search bar that uses Apex to search Cases, and another that searches Opportunities. For example:

@AuraEnabled
public static List<Case> searchCases(String searchKey) 
{
    String name = '%' + searchKey + '%';
    if(!Case.SObjectType.getDescribe().isAccessible()){
        return null;
    }else 
    {
        return 
        [   
            SELECT Account.Name,Subject,Status,CreatedDate, Contact.Name, Priority
            FROM Case
            WHERE Subject LIKE :name OR Account.Name LIKE :name
            ORDER BY LastViewedDate DESC
        ];
    }
}

Now, I want to provide search integration with custom objects, which the admin will be able to specify from a pulldown menu when they drop the component on the page in page builder. I built a class to create the list of custom objects, and I've wired that into the .design file of the component. So now, my search bar component will be able to access the name of the custom object -- let's say Applicants__c, for example.

enter image description here

Now, I'm creating a the search bar functionality where I'll be searching the Name field of the custom object. I'll call the apex method, providing the searchKey and the name of the custom object. I need help figuring out how to use that dynamic custom object name to check for accessibility, and to execute the search. So the first part...

I tried this:

@AuraEnabled
public static List<Object> searchRecords(String searchKey, String custObj) 
{
    String name = '%' + searchKey + '%';
    if(!custObj.SObjectType.getDescribe().isAccessible()){
        return null;
    }else ...

And got this error:

Variable does not exist: SObjectType

I also tried specifying the incoming param as an SObject and an SObjectType, with no luck. Same error when I try to push to scratch org.

The docs say you can't bind the FROM aspect of a SOQL search, so I figure I'll build the string dynamically. Here's my best shot, which is compiling ok.

@AuraEnabled
public static List<Object> searchRecords(String searchKey, String custObj) 
{
    String name = '%' + searchKey + '%';
    if(!custObj.SObjectType.getDescribe().isAccessible()){
        return null;
    }else 
    {
        String searchQuery = 'FIND :name IN NAME FIELDS RETURNING :' + custObj + '(Name,LastModifiedDate)';
        return search.query(searchQuery);
    }
}

Any tips welcome. Thanks.

2 Answers 2

0

What you need on the Describe side is the method Schema.describeSObjects(), which can be called with an arbitrary object name or names:

if (Schema.describeSObjects(new List<String>{ custObj })[0].isAccessible()) {

(Handling for failure cases omitted).

It's true that you cannot bind the FROM in a SOQL query, but you certainly can build the entire query dynamically. (You switched to SOSL in the second example; was that expediency or objective?) As an illustration:

return Database.query(
    String.format(
        'SELECT Name FROM {0} WHERE Name LIKE \'\'{1}\'\' ' +
        'ORDER BY LastViewedDate DESC'
        new List<String> {
            custObj,
            '%' + searchKey + '%'
        }
    )
)
9
  • Thanks @David, that's sleek. RE: SOSL... I'll probably use SOQL here, but in another handler, I'll be using hasRecordId and doing a SOSL search on all fields in those custom objects to pull up related records. Jul 3, 2018 at 15:37
  • Now that I'm working with your code, I don't understand what you're doing with the new List<String>. Jul 3, 2018 at 15:51
  • String.format() takes a List<String> of parameters to use in populating merge fields (like {0}, {1}). The format parameters for this dynamic SOQL query are the object ({0}) and the search key ({1}). (I omitted it, but the search key should be escaped too).
    – David Reed
    Jul 3, 2018 at 15:52
  • One can do dynamic SOQL by simply concatenating strings, but I prefer to write out the template structure and perform substitution with String.format() for clarity.
    – David Reed
    Jul 3, 2018 at 15:53
  • Oh... thanks for the lesson. I've never seen that before. Jul 3, 2018 at 16:04
0
@AuraEnabled
public static List<Object> searchRecords(String searchKey, String custObj) 
{
    String name = '%' + searchKey + '%';
    if(!Schema.getGlobalDescribe().get( custObj ).getSObjectType().getDescribe().isAccessible()){
        return null;
    }else ...

this should get the what you need it

OR Simply

public static Map<String, Schema.SObjectType> allObjects { get; set; }

@AuraEnabled
public static List<Object> searchRecords( String srchKey, String objectName ){

     if( allObjects == null ){
         allObjects = Schema.getGlobalDescribe();
     }

     if( allObjects.containsKey( objectName ) && allObjects.get( objectName ).getDescribe().isAccessible()){
          ......
     }
     else { 
          .....

     }
}
0

You must log in to answer this question.

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