+ Start a Discussion
Jeremiah CochranJeremiah Cochran 

dynamic SOQL query not returning data stored in field queried

Here is the context of what I'm trying to do. I have a lightning component that I want to be able to use on any object so I have added an attribute to the design file that allows a user to enter the API Name of the field that data should be retrieved from. I have a dynamic SOQL query that takes in variables for the sobject type and the field the user indicated. However, the returned result is the ID for the object record, not the data stored in the field. How do I get the actual data from the field?

Here is my code:

public with sharing class ProgressBarControler{
    
    @AuraEnabled
    public static List<String> getProgress(Id recordId, String fieldName)
    {
        List<String> progress = new List<String>();
           
        Id myId = recordId;
        system.debug('the record Id is '+myId);
        
        String objfieldName = fieldName;
        system.debug('the fieldName is '+objfieldName);
        

        String sObjName = myId.getSObjectType().getDescribe().getName();
        system.debug('the sObjectName is '+sObjName);
		
         SObjectType sObjType = Schema.getGlobalDescribe().get(sObjName);
        
        // Create Dynamic Query Start ..
        String theQuery = 'SELECT ';
        // Insert field name variable into Query
        theQuery += objfieldName + ',' ;
               system.debug('the field name is '+objfieldName); 
        
        // Trim last comma
        theQuery = theQuery.subString(0, theQuery.length() - 1);
        // Finalize query string
        theQuery += ' FROM '+sObjType+' LIMIT 1';
        // Query End ..
        System.debug('theQuery = '+theQuery);            
            
            Object o = Database.Query(theQuery);
            
        String returnValue = String.valueOf(o);
               
                progress.add(returnValue);
            	System.debug('the return value = '+returnValue);
        
        return progress;
    }
}

 

Best Answer chosen by Jeremiah Cochran
Jeremiah CochranJeremiah Cochran

Hi All, Thanks for the suggestions. I was able to resolve the issues using the documentation found here: 
https://opfocus.com/dynamic-field-binding-in-salesforce-lightning-experience/

Essentially I had to simplify my APEX controller and change it to return a sObject and in my Component Controller I had to use this:

component.set("v.progress",sobjectrecord[fieldName]);
After making those changes it works perfectly.

 

 

All Answers

Steven NsubugaSteven Nsubuga
Just tested it, in my Developer Console, it works beautifully. I think you are probably passing in a wrong record Id. Check your method call.
Jeremiah CochranJeremiah Cochran
Hi @Steven Nsubuga, It should not be returning a record ID. It should be returning the data stored in the field passed in using the attribute "fieldName". So for example, if "fieldName" is number__c and on the record, that field has a value of 20, the query should return 20 however it is returning the recordID.
Steven NsubugaSteven Nsubuga
I ran it with the code below
List<Contact> ct = [Select Id FROM Contact WHERE Name = 'Yeaaaaaaaah'];
ProgressBarControler.getProgress(ct[0].Id, 'Name');
and got this
User-added image
Seems good to me.
Steven NsubugaSteven Nsubuga
Scratch that, it returned a totally different Contact!! The issue is with the query!! You forgot to add a WHERE clause to make use of the record ID!!
public with sharing class ProgressBarControler{
    
    @AuraEnabled
    public static List<String> getProgress(Id recordId, String fieldName)
    {
        List<String> progress = new List<String>();
           
        Id myId = recordId;
        system.debug('the record Id is '+myId);
        
        String objfieldName = fieldName;
        system.debug('the fieldName is '+objfieldName);
        

        String sObjName = myId.getSObjectType().getDescribe().getName();
        system.debug('the sObjectName is '+sObjName);
        
         SObjectType sObjType = Schema.getGlobalDescribe().get(sObjName);
        
        // Create Dynamic Query Start ..
        String theQuery = 'SELECT ';
        // Insert field name variable into Query
        theQuery += objfieldName + ',' ;
               system.debug('the field name is '+objfieldName); 
        
        // Trim last comma
        theQuery = theQuery.subString(0, theQuery.length() - 1);
        // Finalize query string
        theQuery += ' FROM '+sObjType+ ' WHERE Id =  :myId' + ' LIMIT 1 ';
        // Query End ..
        System.debug('theQuery = '+theQuery);            
            
            Object o = Database.Query(theQuery);
            
        String returnValue = String.valueOf(o);
               
                progress.add(returnValue);
                System.debug('the return value = '+returnValue);
        
        return progress;
    }
}

 
Jeremiah CochranJeremiah Cochran

Thanks, One problem solved. The value is showing in the debug log now however it is not being set in the lightning component. Here is my code for that:

doInit : function(component, event, helper) {
        var recordId = component.get("v.recordId");
        var sObjectName = component.get("v.sObjectName");
        var fieldName = component.get("v.fieldName");
        
        var action = component.get("c.getProgress");
        action.setParams({
            	"recordId": recordId,
                "fieldName": fieldName
            	
            
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var progress = response.getReturnValue();
                
                component.set("v.progress", progress);
            }
               });
        
        $A.enqueueAction(action);

Here is the attribute that should set by the code above:

<aura:attribute name="progress" type="integer" default="0"/>

Steven NsubugaSteven Nsubuga
My guess, is that the return value as seen in the debug log and the method signature is that not a single value but a list of Strings.
A list of strings cannot go into an Integer, which is what your component is set up to display. Either change the return type of the method or the type of "progress"
Ravi Dutt SharmaRavi Dutt Sharma
In your apex class, change line 6 to 
String progress = '';

In your component, change the attribute to below:
<aura:attribute name="progress" type="String"/>

 
Jeremiah CochranJeremiah Cochran

@Ravi Dutt Sharma

When I try to make the changes you suggest I get this error: Method does not exist or incorrect signature: void add(String) from the type String

Steven NsubugaSteven Nsubuga
Change only the component, not the Apex class
Jeremiah CochranJeremiah Cochran
@Steven Nsubuga, I changed the Component only, however, the value is still not displaying there.
Ravi Dutt SharmaRavi Dutt Sharma
progress = returnValue; Regards, Ravi Dutt Sharma
Jeremiah CochranJeremiah Cochran

Hi All, Thanks for the suggestions. I was able to resolve the issues using the documentation found here: 
https://opfocus.com/dynamic-field-binding-in-salesforce-lightning-experience/

Essentially I had to simplify my APEX controller and change it to return a sObject and in my Component Controller I had to use this:

component.set("v.progress",sobjectrecord[fieldName]);
After making those changes it works perfectly.

 

 

This was selected as the best answer