The only documented difference that I can find between the @RemoteAction Annotation and Non-Annotated apex methods is this section from the Apex Developer Guide (https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_RemoteAction.htm):
RemoteAction Annotation
The RemoteAction annotation provides support for Apex methods used in Visualforce to be called via JavaScript. This process is often referred to as JavaScript remoting.
However, consider the following controller:
public without sharing class CPQController {
public CPQController(){}
@RemoteAction
public static List<SBQQ__Quote__c> getQuotesRemote(){
List<SBQQ__Quote__c> quotes = [SELECT Id,Name FROM SBQQ__Quote__c];
return quotes;
}
public List<SBQQ__Quote__c> getQuotes2(){
List<SBQQ__Quote__c> quotes = [SELECT Id,Name FROM SBQQ__Quote__c];
return quotes;
}
}
And the following Visualforce:
<apex:page sidebar="false" showHeader="false" controller="CPQController">
<html>
<head>
<title>REST Test</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>Loading...<br />
<div Id="main">
<div Id="QuotesRemote">
<button onclick="getQuotesRemote();">Get Quotes Remote</button><br />
<h1>Quotes Remote:</h1><br />
<apex:repeat value="{!quotesremote}" var="qr">
QR: {!qr.Id}<br />
</apex:repeat>
</div>
<div Id="Quotes">
<h1>Quotes:</h1><br />
<apex:repeat value="{!quotes2}" var="q">
Q: {!q}<br />
</apex:repeat>
</div>
</div>
<script type="text/javascript">
function getQuotesRemote() {
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.CPQController.getQuotesRemote}',
function(result, event){
if (event.status) {
for(var i = 0;i < result.length;i++){
document.getElementById('QuotesRemote').innerHTML += 'QR2: ' + result[i].Id + '<br />';
}
}
},
{escape: true}
);
}
</script>
</body>
</html>
</apex:page>
Scenario 1: Visualforce Page Accessed by User with Managed Package License
Result:
- The
Quotes
div is Populated with the Quote Ids from<apex:repeat />
, - Pressing the "Get Quotes Remote" button appends the Quote Ids to the
QuotesRemote
div.
Scenario 2: Visualforce Page Accessed by User without a Managed Package License
Result:
- The
Quotes
div is populated with a bunch of blank rows that start withQ:
. Presumably because the SOQL is returning empty record(s), but the list itself is still iterated (not empty)? (see Screenshot below). - Pressing the "Get Quotes Remote" button still appends the Quote Ids to the
QuotesRemote
div, contradicting the behavior ofgetQuotes2()
, which runs the same SOQL query.
Is there a documented reason for this difference? I don't mind the behavior, but I also don't want to use Javascript Remoting to work with records if this undocumented behavior is subject to change.