sforce.apex.execute not working in Lightning experience

  • 1
  • Problem
  • Updated 2 months ago
  • Solved
Hi All,

sforce.apex.execute works well in classic mode with snippet, but fail in Lightning experience.

Any help is appreciated.

Photo of Kevin

Kevin

  • 852 Points 500 badge 2x thumb

Posted 2 years ago

  • 1
Photo of Mark DeSimone

Mark DeSimone, Official Rep

  • 12,352 Points 10k badge 2x thumb
Hi Kien, since this is a Salesforce command, you will probably need to look through Salesforce's documentation or discussion boards for the best information. https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_and_ajax.htm is probably a good starting point.
Photo of Zach McElrath

Zach McElrath, Employee

  • 54,246 Points 50k badge 2x thumb
Kien,

Use of sforce.apex.execute is no longer recommended --- the recommended approach, which will allow any Apex code to be "invocable" from both Classic/Visualforce and Lightning Experience, without writing any JavaScript, is to expose your Apex logic via an "InvocableMethod". Skuid then allows you to call Invocable Methods using the "Run Data Source Action" action type in the Action Framework, so that you can eliminate any JavaScript. 

See this tutorial for more details:

https://docs.skuid.com/latest/en/skuid/salesforce/apex/apex-invocable-methods.html

Any Apex logic that you currently have exposed via the WebService annotation could fairly easily be adjusted to be exposed as an Invocable Method, which would allow this logic to be invoked from any Skuid Page, running in any Salesforce environment. As an added benefit, it also enables the logic to be invoked from Process Builder / Visual Workflow.

This is what we recommend --- "sforce.apex.execute" is only available in Classic/Visualforce.
Photo of Kevin

Kevin

  • 852 Points 500 badge 2x thumb
Hi Zach,

I want to pass the Id of records when a user checks multiple rows in a table. How can I pass them to InvocableVariable?

Thanks.
Photo of Zach McElrath

Zach McElrath, Employee

  • 54,246 Points 50k badge 2x thumb
One way would be to combine them into an array and then JSON stringify them. You can create a Ui-Only Model to store the Ids and then populate a value in that Ui-Only Model's row, then use that when populating the Invocable Variable. Something like this, could be put into a snippet and then run this snippet prior as part of the action sequence, immediately prior to the "Run Data Source Action" where you invoke the Apex:

(Assuming a Ui-only Model exists with name "Ui" and a default row exists in it, and there's a field called "RowIds")

var model = skuid.$M("Ui");
var row = model.getFirstRow();

var rowIdsString = JSON.stringify(params.list.getSelectedItems().map(function(item) {
   return item.row.Id;
}));

model.updateRow(row, "RowIds", rowIdsString);

And then add an InvocableVariable to your Invocable Method whose name is "RowIds", and populate it in Skuid with the value {{$Model.Ui.data.0.RowIds}}
Photo of Kevin

Kevin

  • 852 Points 500 badge 2x thumb
Thank Zach.

Please help to mark this thread to Solved.
(Edited)
Photo of Kevin

Kevin

  • 852 Points 500 badge 2x thumb
Hi  Zach,

I'm using Invocable Methods and the Apex Data Source Action. In Apex class, there is a method returns a string value. Then I want to display this result on Skuid page by Popup.

How can I do it?
Photo of Mike Dwyer

Mike Dwyer, Champion

  • 4,736 Points 4k badge 2x thumb
This thread ended with an unanswered question. The answer is available elsewhere (sorry, I don't have that link). But, this is what I have implemented to display a String result from the apex class:

First, the old style apex class and method was ...
global class myTest {
    
    webservice static String stringTestOldStyle( String yourName )
    {
        return 'Hello, ' + yourName;
    }
}
This was called in an Inline Snippet as ...
var result = sforce.apex.execute(
    'myTest', stringTestOldStyle', {
        yourName:'World' }
);
alert(result);
The changed class looks like this:
global class myTest {
    // Define parameter(s) visible to skuid "Run Data Source Action / Salesforce / Apex"
    global class Parameters {
        @InvocableVariable(required=true description='A first or last name' label='Your Name') 
            public String aName;
    }
    // Define method name visible to skuid "Run Data Source Action / Salesforce / Apex / Action"
    @InvocableMethod( label='String Test Lightning Style')
    global static List<String> stringTestNewStyle ( List<Parameters> parameterList ) 
    {
        List <String> retVals = new List <String>(); // skuid will only see element [0]
        retVals.add('Hello, ' + parameterList[0].aName);
        return retVals;
    }
    
}
The returned value available to skuid is retVals[0], so do not add elements to the List!

The method myTest.stringTestNewStyle() is called with the Run Data Source Action action type. The Data Source is "salesforce" and the Action is "Apex." The Apex Action "String Test Lightning Style" will be exposed to the skuid page editor.

The parameter "Your Name" will also be exposed to the page editor. Enter a fixed string (World) or a skuid value like {{$User.firstName}}.

(The apex names exposed in skuid are the InvocableMethod and InvocableVariable 'label' values.) 


Finally, the answer to Kevin's last question:

With this structure, the return value ["Hello, World"] may be displayed with the Show Message action using {{$PreviousAction.result.output}}. This action would follow the Run Data Source Action. Alternatively, you can use {{$PreviousAction.result.output}} in a snippet to populate an alert or write to the console (for example).


===========================================================

===========================================================

============================================================