JavaScript Remoting for Apex Controllers

Use JavaScript remoting in Visualforce to call methods in Apex controllers from JavaScript. Create pages with complex, dynamic behavior that isn’t possible with the standard Visualforce AJAX components.

JavaScript remoting has three parts:

Adding JavaScript Remoting to a Visualforce Page

To use JavaScript remoting in a Visualforce page, add the request as a JavaScript invocation with the following form:
[namespace.]controller.method(
    [parameters...,]
    callbackFunction,
    [configuration]
);
  • namespace is the namespace of the controller class. This is required if your organization has a namespace defined, or if the class comes from an installed package.
  • controller is the name of your Apex controller.
  • method is the name of the Apex method you’re calling.
  • parameters is the comma-separated list of parameters that your method takes.
  • callbackFunction is the name of the JavaScript function that will handle the response from the controller. You can also declare an anonymous function inline. callbackFunction receives the status of the method call and the result as parameters.
  • configuration configures the handling of the remote call and response. Use this to change the behavior of a remoting call, such as whether or not to escape the Apex method’s response.

The remote method call executes synchronously, but it doesn’t wait for the response to return. When the response returns, the callback function handles it asynchronously. See Handling the Remote Response for details.

Configuring JavaScript Remoting Requests

Configure a remoting request by providing an object with configuration settings when you declare the remoting request. For example, the default configuration parameters look like this:
{ buffer: true, escape: true, timeout: 30000 }
These configuration parameters aren’t ordered, and you can omit parameters you don’t want to change from the default.
JavaScript remoting supports the following configuration parameters:
NameData TypeDescription
bufferBooleanWhether to group requests executed close to each other in time into a single request. The default is true.

JavaScript remoting optimizes requests that are executed close to each other in time and groups the calls into a single request. This buffering improve the efficiency of the overall request-and-response cycle, but sometimes it’s useful to ensure all requests execute independently.

escapeBooleanWhether to escape the Apex method’s response. The default is true.
timeoutIntegerThe timeout for the request, in milliseconds. The default is 30000 (30 seconds). The maximum is 120000 (120 seconds, or 2 minutes).
The request timeout can also be configured for all requests made by a page, by setting the timeout using the Visualforce remoting object:
<script type="text/javascript">

    Visualforce.remoting.timeout = 120000; // Set timeout at page level

    function getRemoteAccount() { var accountName = document.getElementById('acctSearch').value; // This remoting call will use the page's timeout value Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.AccountRemoter.getAccount}', accountName, handleResult ); } function handleResult(result, event) { ... } </script>

Override a page-level timeout configuration on a per-request basis by setting the timeout in the configuration object for that request, as described above.

OAuth 2.0 Authentication for JavaScript Remoting

JavaScript remoting requests can use OAuth 2.0 for authentication, instead of requiring a standard username and password login process. OAuth allows cross-application and cross-org integrations that aren’t possible to do securely with standard authentication.

A Visualforce page that uses OAuth for authentication configures it at the page level, and uses OAuth for all JavaScript remoting requests. Other than configuration, using JavaScript remoting is exactly the same.

Configuring OAuth for JavaScript remoting from a Visualforce page takes the following form:
<script type="text/javascript">

    Visualforce.remoting.oauthAccessToken = <access_token>;

    // ...
</script>
Once oauthAccessToken is set, all JavaScript remoting requests use OAuth. The rest of your JavaScript remoting code can remain the same.

oauthAccessToken is an OAuth authentication token obtained by your page’s code. Obtaining and updating an access token is straightforward OAuth, with one addition. JavaScript remoting OAuth authentication requests the “visualforce” scope, so your token must be generated with this or a scope that contains it, including “web” or “full”. Set scope=visualforce (or “web” or “full”) in your OAuth request.

For information about obtaining access tokens, and using OAuth with the Force.com platform, see Authenticating Remote Access Applications in the Salesforce online help and wiki.developerforce.com/page/Digging_Deeper_into_OAuth_2.0_on_Force.com.

Namespaces and JavaScript Remoting

To make it easier to work with namespaces, especially for pages that make remoting calls to methods provided in packages, you can use the $RemoteAction global to automatically resolve the correct namespace, if any, for your remote action. To use this facility, you must explicitly invoke JavaScript remoting. The pattern for doing this is:
Visualforce.remoting.Manager.invokeAction(
    'fully_qualified_remote_action', 
     invocation_parameters
);

The fully qualified remote action is a string that represents the complete path to the remote action method, including namespace, base class, and so on: namespace[.BaseClass][.ContainingClass].ConcreteClass.Method. Use $RemoteAction in an expression to automatically resolve the namespace, for example {!$RemoteAction.MyController.getAccount}.

Invocation parameters are the arguments used to perform the remote method invocation, and are the same arguments used to make a standard remoting call:
  • The parameters to send to the @RemoteAction method, if any.
  • The callback function, which handles the returned result.
  • Configuration details for the invocation, if any.
For example, you might define a remote invocation to retrieve an account like this:
<script type="text/javascript">
function getRemoteAccount() {
    var accountName = document.getElementById('acctSearch').value;

    Visualforce.remoting.Manager.invokeAction(
        '{!$RemoteAction.MyController.getAccount}', 
        accountName, 
        function(result, event){
            if (event.status) {
                document.getElementById('acctId').innerHTML = result.Id
                document.getElementById('acctName').innerHTML = result.Name;
            } else if (event.type === 'exception') {
                document.getElementById("responseErrors").innerHTML = event.message;
            } else {
                document.getElementById("responseErrors").innerHTML = event.message;
            }
        }, 
        {escape: true}
    );
}
</script>
This JavaScript remoting call doesn’t need to know the details of the namespace in which the controller is defined, whether it’s in your own namespace or something provided by an installed package. It also handles the situation where your organization doesn’t have a namespace defined.
Note
Errors encountered when calling invokeAction are reported only in the JavaScript console. For example, if $RemoteAction finds matching @RemoteAction methods in multiple namespaces, it returns the first matching method and logs a warning to the JavaScript console. If a matching controller or action is not found, the call silently fails and an error is logged to the JavaScript console.

Declaring a Remote Method

In your controller, your Apex method declaration is preceded with the @RemoteAction annotation like this:
@RemoteAction
global static String getItemId(String objectName) { ... }

Your method can take Apex primitives, collections, typed and generic sObjects, and user-defined Apex classes and interfaces as arguments. Generic sObjects must have an ID or sobjectType value to identify actual type. Interface parameters must have an apexType to identify actual type.

Your method can return Apex primitives, sObjects, collections, user-defined Apex classes and enums, SaveResult, UpsertResult, DeleteResult, SelectOption, or PageReference.

Methods used for JavaScript remoting must be uniquely identified by name and number of parameters; overloading isn’t possible. For instance, with the method above, you can’t also have a getItemId(Integer productNumber) method. Instead, declare multiple methods with different names:
  • getItemIdFromName(String objectName)
  • getItemIdFromProductNumber(Integer productNumber)
Your Apex method must be static and either global or public. Globally-exposed remote actions should not perform sensitive operations or expose non-public data. global remote actions may only call other global methods. public remote actions may not be used in global components, or otherwise used in a global scope. Scope escalation will result in a compiler error or, for references which are resolved at runtime, a runtime failure. The following table describes these restrictions in more detail:
@RemoteAction ScopeVisualforce PageNon-Global ComponentGlobal Componentiframe
Global Remote MethodAllowedAllowedAllowedAllowed
Public Remote MethodAllowedAllowedErrorError
When remote actions are accessed via markup that is included indirectly, via components or the <apex:include> or <apex:composition> tags, the scope of the remote method is carried forward into the top level container, that is, the top level item in the inclusion hierarchy, which must abide by scope escalation rules:
Top Level Container
@RemoteAction Accessed FromVisualforce PageNon-Global ComponentGlobal Componentiframe
Global ComponentAllowedAllowedAllowedAllowed
Non-Global ComponentAllowedAllowedAllowed only if non-global component doesn't include public remote methods.Allowed only if non-global component doesn't include public remote methods.
<apex:include><apex:composition>Allowed within the same namespace; error if namespaces are different, and the included page or its child hierarchy contains public remote methods.n/an/aError

Remote Methods and Inheritance

When a @RemoteAction method is looked up or called, Visualforce inspects the page controller’s inheritance hierarchy and finds @RemoteAction methods in the controller’s ancestor classes.

Here’s an example demonstrating this capability. The following Apex classes form a three-tier inheritance hierarchy:
global with sharing class ChildRemoteController 
    extends ParentRemoteController { }
global virtual with sharing class ParentRemoteController 
    extends GrandparentRemoteController { }

global virtual with sharing class GrandparentRemoteController {
    @RemoteAction
    global static String sayHello(String helloTo) {
        return 'Hello ' + helloTo + ' from the Grandparent.';
    }
}
This Visualforce page simply calls the sayHello remote action.
<apex:page controller="ChildRemoteController" >
    <script type="text/javascript">
        function sayHello(helloTo) {
            ChildRemoteController.sayHello(helloTo, function(result, event){
                if(event.status) {
                    document.getElementById("result").innerHTML = result;
                }
            });
        }
    </script>

    <button onclick="sayHello('Jude');">Say Hello</button><br/>
    <div id="result">[Results]</div>
    
</apex:page>
The remote method doesn’t exist in the ChildRemoteController class. Instead, it’s inherited from GrandparentRemoteController.

Declaring a Remote Method with Interface Parameters

You can declare @RemoteAction methods with interface parameters and return types, instead of being restricted to concrete classes. This, for example, allows a package provider to package a remote method and associated interface, which subscriber organizations can call from Visualforce pages, passing in their own class that implements the packaged interface.

Here’s a brief example:
public class RemoteController {
    public interface MyInterface { String getMyString(); }
    public class MyClass implements MyInterface { 
        private String myString; 
        public String getMyString() { return myString; }
        public void setMyString(String s) { myString = s; }
    }
    
    @RemoteAction
    public static MyInterface setMessage(MyInterface i) {
        MyClass myC = new MyClass();
        myC.setMyString('MyClassified says "' + i.getMyString() + '".');
        return myC;
    }
}
Objects sent from a JavaScript remoting call to a @RemoteAction that declares interface parameters must include an apexType value, which must be a fully-qualified path to the concrete class, that is, namespace[.BaseClass][.ContainingClass].ConcreteClass. For example, to make a JavaScript remoting call to the above controller:
Visualforce.remoting.Manager.invokeAction(
    '{!$RemoteAction.RemoteController.setMessage}',
    {'apexType':'thenamespace.RemoteController.MyClass', 'myString':'Lumos!'}, 
    handleResult
);
If the class definition is within your organization, you can simplify the remoting call, and also use the default c namespace:
RemoteController.setMessage(
    {'apexType':'c.RemoteController.MyClass', 'myString':'Lumos!'}, 
    handleResult
);

Handling the Remote Response

The response to a remote method call is handled asynchronously by the callback function provided in the remote method call. Your callback function will receive as parameters an event object representing the status of the remote call, and the result object returned by the remote Apex method. Your function can update information and user interface elements on the page based on the data returned.

The event object provides values that let you act upon the success or failure of the remote call:
  • event.status is true on success, false on error.
  • event.type is the type of the response: rpc for a successful call, exception if the remote method threw an exception, and so on.
  • event.message contains any error message that is returned.
  • event.where contains the Apex stack trace, if one was generated by the remote method.

Apex primitive data types returned by result—such as strings or numbers—are converted to their JavaScript equivalents. Apex objects that are returned are converted to JavaScript objects, while collections are converted to a JavaScript array. Keep in mind that JavaScript is case-sensitive, so id, Id, and ID are considered different fields.

As part of a JavaScript remote call, if the Apex method response contains references to the same object, the object won't be duplicated in the returned JavaScript object, and instead, the rendered JavaScript object will contain references to the same object. An example is an Apex method which returns a list that contains the same object twice.

By default, the response of the remote call must return within 30 seconds, after which the call will time out. If your request needs longer to complete, configure a longer timeout, up to 120 seconds.

The response of the remote call has a maximum size of 15 MB.

If your JavaScript remoting code is exceeding this limit, you have several options:
  • Reduce the size of the response for each request. Only return data that’s required.
  • Break up large data retrieval into requests that return smaller chunks.
  • Ensure that you’re using non-batched requests. Set { buffer: false } in your remoting request configuration block.
  • Make batched requests less frequently, reducing the size of the batch.
Note
Keep your JavaScript console open during development when using JavaScript remoting. Errors and exceptions encountered by JavaScript remoting are logged to the JavaScript console, if enabled, and are otherwise silently ignored.
When a @RemoteAction method throws an exception due to a programming error or other failure, the Apex stack trace is returned to the browser. Inspect the stack trace in a JavaScript debugger console or use it in the error handling of your response callback function. Here’s a callback function that simply displays the stack trace when there’s an exception:
<script type="text/javascript">
function getRemoteAccount() {
    var accountName = document.getElementById('acctSearch').value;

    Visualforce.remoting.Manager.invokeAction(
        '{!$RemoteAction.MyController.getAccount}', 
        accountName, 
        function(result, event){
            if (event.status) {
                document.getElementById('acctId').innerHTML = result.Id
                document.getElementById('acctName').innerHTML = result.Name;
            } else if (event.type === 'exception') {
                document.getElementById("responseErrors").innerHTML = 
                    event.message + "<br/>\n<pre>" + event.where + "</pre>";
            } else {
                document.getElementById("responseErrors").innerHTML = event.message;
            }
        }
    );
}
</script>

JavaScript Remoting and <apex:actionFunction>

The <apex:actionFunction> component also lets you call controller action methods through JavaScript. Here are some differences between the two:
  • The <apex:actionFunction> tag:
    • lets you specify rerender targets
    • submits the form
    • does not require you to write any JavaScript
  • JavaScript remoting:
    • lets you pass parameters
    • provides a callback
    • requires you to write some JavaScript

In general, <apex:actionFunction> is easier to use and requires less code, while JavaScript remoting offers more flexibility.

© Copyright 2000–2014 salesforce.com, inc. All rights reserved.
Various trademarks held by their respective owners.