Release notes can contain some wonderful surprises in them, as Quinton mentioned – it’s always good to looking for some gems in there.  Spring ‘11 is rolling out to general availability now, so you’ve either got your hands on it or should very soon.  While we’ve talked a lot about some of the great new features with the REST API or Chatter, let’s look at one that is a little more under the radar at the moment: JavaScript Remoting.

And when I say under the radar, I should more accurately put it that remoting is on the radar.  While some docs might suggest the feature is in Developer Preview, it’s really in more of a trial period.  This means there isn’t a quick way to register for a specific kind of org like we had for the REST preview, you’ll have to get in touch with technical support to enable the feature on a Spring ‘11 enabled org.  Feel free to email me (that’s joshua.birk at the domain one might suspect…) or tweet mewith an org ID and I’ll see about getting you the hookup.So what is JavaScript Remoting?  Essentially the feature allows for quick, tight integration between Apex and JavaScript.  If you had used the old AJAX toolkit in the past, it’s similar in some ways to how accessing an Apex Web Service worked – but is far more lightweight and simpler to get up and running.

First, you’ll need an globally scoped Apex class, with a static function defining the logic you want JavaScript to access.  By adding the RemoteAction annotation, you’ll be letting Visualforce know it should wrap this logic in a JavaScript friendly way:

global class remoteTest {
@RemoteAction
global static Contact[] findContacts(string Name) {
Name = '%'+Name+'%';
Contact[] c = [SELECT ID, Name, Phone, Email from Contact where NAME LIKE :Name ];
return c;
}
}

From there, associate the Visualforce to the class as a controller or extension, and Visualforce will include the ability to call the method from JavaScript.  The framework works on asynchronous results, so after passing in your params, you can grab the result from a handler function.  In this case, I’m taking my list of contacts and assigning it to a global array for use.

var contacts;
function contactSearch(name) {
remoteTest.findContacts(name,handleContacts);
}
function handleContacts(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
contacts = result;
showContacts();
}
}

Then I can access the contacts and the fields I brought down with SOQL. In this example, I’ll use the returned array of contacts to browse for email and phone numbers. Here’s the complete, albiet quick and rough, Visualforce page:

var contacts;
function contactSearch(name) {
remoteTest.findContacts(name,handleContacts);
}
function handleContacts(result, event) {
if(event.type == 'exception') {
alert(event.message);
} else {
contacts = result;
showContacts();
}
}
function showContacts() {
var newList = "";
for(var i = 0; i < contacts.length; i++) {
newList += "
";
}
document.getElementById('contactList').innerHTML = newList;
}
function showContact(index) {
document.getElementById('phone').innerHTML = 'Phone: '+contacts[index].Phone;
document.getElementById('email').innerHTML = 'Email: '+contacts[index].Email;
}


And there you have it – with minimal overhead and effort, I have JavaScript powered by Apex in a client friendly manner.  While the event object returned in the callback includes the type (so that you can determine if there was an error) and message (to get the proper error message from Apex), you can also poke around there and see which class and method you were calling from Apex if you need it.  They are the action and method fields on the event object, respectively.

It’s pretty exciting stuff, and I can’t wait to see how it works with a certain library that rhymes with “jQuery”.  Again though, remember this isn’t ready for the mass public right away as we’re still tinkering with it – but if you want to enable this on a Spring ’11 org, contact technical support or shoot me an email or catch me on twitter.

 

tagged , , , , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Gene Koopman

    I noticed this also in the release notes, and have real need for this functionality on a project I’m working on right now. This kind of integration is exactly what I’ve been waiting for. I would much rather use JQuery and HTML than Flex. I’ve never been a fan of Flash, and I didn’t want to have to learn it just to build rich UI in Force.com. I hope this is released for real sooner rather than later.

  • http://Www.tgerm.com Abhinav

    Great post, since I saw this remoting feature in release notes,i was after it and waiting for spring release to hit my dev org since e can’t get it in pre release ones.

  • http://www.luminosity-group.com Richard Summerhayes

    Very Excited about this, going to be huge for Front End Development.

  • http://Www.Arrowpointe.com Scott Hemmeter

    I keep trying to understand how this is different than using an actionFunction on a page that rerenders JavaScript for execution in response to the call. Can u explain? I’ve been accessing Apex from JavaScript for a while now, even from jQuery. There is obviously something I must not be understanding. Perhaps this is functionality more meant to get a response back from Apex than the hacked approach of rerendering JavaScript?

  • Josh

    I think the intent is offer some more flexibility, and give another tool to the toolkit than just using actionFunction. You absolutely could do this example using actionFunction, and certainly nothing stopping you from using jQuery, but this provides a route for client/server interaction without relying on that particular part of the VF framework. There’s undoubtably still good use cases for scenarios which are “heavy” Visualforce, but now if you have “heavy” JavaScript UI – it should make development easier.

  • https://www.adaptu.com/ Vijay

    Remoting and security like DWR has and what features are available would be nice.Do you have to login from client JS using JQuery-where does the login info get stored on the client ?

  • Josh

    Vijay: when using JavaScript, including jQuery, in this way you would already be authenticated within the Force.com environment. So you don’t have to store credentials anyway, it’s the same as developing Visualforce in general.

  • http://www.financialforce.com Andrew Fawcett

    Great to see this. In answer to another question above, I believe one key difference, for those with large view states, over actionFunction is that it doesn’t need to exchange the view state with the server? Hence these should be a lot faster!
    Josh, can we make using global optional somehow? I really hate to nail in methods like these, that suppor the internal workings of our pages. Sure if we want to expose apex methods for integration or developer usage, but can have this choice please? Without deprication we have to live with them once the package is uplaoded.

  • http://www.financialforce.com Andrew Fawcett

    Oh yes, another question, will these calls count against the org daily API limit or not? I surely hope not, but just incase wanted to ask.

  • Josh

    Andrew: it certainly doesn’t cost an API call, and true: I don’t believe the viewstate would get involved here, it doesn’t technically require a form tag or the like (as we can see this example.
    I’ll ask around about global being optional. Still in trial, so I’d say keep an eye on it for any changes.

  • http://tehnrd.com Jason

    I’m sort of in the same boat as Scott Hemmeter. I’m not sure I see the value of using this over a typical actionFunction, which includes a built in rerender attribute. Rarely ever will I call a server method to get data and not perform a rerender, which is basically what js remoting does. It makes calling a method from js-to-apex easier than actionFunction but you must completely handle the response and do the “re-render” with javascript yourself. Move flexible yes, but also more work and more complicated.
    What made Visualforce, in use with the standard components, so appealing to me in the first place is that I don’t have to mess with the response using javascript to manipulate the output. Rerender…done.

  • Sandeep

    Jason – You’re correct in that JS Remoting does not directly support AJAX rerendering (though you could achieve the same via JS) as compared to actionFuction. However, there are a couple of other advantages/differences between JS Remoting and actionFunction that should be considered :
    1) You can pass in parameters (primitives only) and return data (primitives of SObjects) in JS Remoting. You can’t do that with actionFunction. This may be very important in certain use cases where you’re doing heavy-duty JS logic and want to exchange data with the server (where presumably some business logic executes).
    2) As Andrew pointed out, since the view state is not passed back and forth in a JS Remoting call (since the form is not submitted), it is generally faster than a actionFunction call.

  • Stephan Morais

    To answer some of the questions/comments in this thread:
    Re: How is this different than actionFunction?
    As noted in other posts, the difference is that:
    1) We don’t have to deal with view state, so it’s generally more performant. Also note that with JavaScript Remoting we handle the JSON serialization of the response for you, so you don’t have to deal with that yourself in Apex, which may be slow and/or cumbersome.
    2) It’s easier to pass args to the Apex method with this approach.
    See also the chapter in the Visualforce Developer Guide that speaks to how the approaches differ:
    http://www.salesforce.com/us/developer/docs/pages/index_Left.htm#StartTopic=Content/pages_js_remoting.htm
    Re: Global as a requirement
    The trick here is that we would need some somehow make sure that you couldn’t call into a JavaScript remoted method outside of the page for which it was intended to be called from. There are ways to do this, but they add some complexity, and we opted to defer this for now. We’re looking into it for a future release.
    Re: DWR
    I’ve been a big fan of DWR for many years. JS Remoting is very much inspired by my experience with DWR style development.
    Other comments…
    The intent with JS Remoting is to offer you an option that may be useful in some cases. If actionFuntion and rerender work for you today, great! But there are a lot of use cases where remoting may be the better approach — it depends on what you’re trying to do.
    By way of example, see the “There’s more than one way to do it” part of my Dreamforce presentation:
    //www.youtube.com/watch?v=gXj0djp2144
    Also worth mentioning is that this approach applies to more than just JQuery. If there are any Ext developers out there, note that we’ve basically implemented the Ext.Direct spec for Apex. See:
    http://www.sencha.com/products/extjs/extdirect/
    Lastly, we’re looking for more feedback to help us refine this feature in a way that helps JavaScript style development. We’re looking at relaxing the global requirement, and also at allowing you to use both Apex object instances and sObjects in the request args and response. What else are you looking for?
    …stephan

  • http://tehnrd.com Jason

    Hey Stephan,
    Thanks for the detailed response. There is no doubt passing arguments to the apex method is the best improvement but for me I don’t think its value out weighs what you lose. This approach isn’t that hard, http://blog.sforce.com/sforce/2009/10/passing-javascript-values-to-apex-controller.html , and you don’t have to mess with the response.
    JS remoting doesn’t send the viewstate to controller but you should be able to minimize the effect of this by using transient objects and actionRegion…well, at least the POST size would be smaller but I think the response would be sames size.
    In the end I see js remoting good for two reason. It will probably give you better page performance, assuming you aren’t handling the response inefficiently, and full control over then entire transaction. Yet this all comes the cost of more complexity. Me, I’ll stick with the rerenders and standard apex components for now. I don’t want to parse a response, format values like dates and currencies. This is exactly the reason I despised s-controls so much and love VF. It removes the complexity in the middle of the process of executing a method and displaying the data.
    Ok, I’ll get off the soapbox now ;-)

  • http://verticalcode.wordpress.com Daniel

    Just posted a blog post on using remoting to build an autocomplete component: http://verticalcode.wordpress.com/2011/02/19/salesforce-javascript-remoting-jquery-and-autocomplete/. I liked how easy it was to use Apex on the backend to build my complex logic and return it to jQuery. I’d love to hear how I could improve my code if anyone has any suggestions.

  • http://www.arrowpointe.com Scott Hemmeter

    I get it now. It’s similar in nature to actionFunction, but doesn’t have all the baggage of the View State. That’s pretty huge and I can think of many uses for it now. I’ve gone to great lengths to minimize and even avoid adding things to View State and this is a new tool in my quiver.
    I’d like to echo Andrew’s feedback about the methods being Global. His reasons were for exposure to customers and I agree with that. Another reason to drop the global requirement is that global method signatures are locked down in a managed package and it requires a new version installable by the customer (no push upgrades) to change or add new ones. It would be great if these were not required to be global in scope.

  • http://www.3gurus.com Ajay

    Josh, this is indeed a nice post, a small clarification needed here that if we get it enabled for our org and use the feature in our code, will it become a prerequisite for the package deployment on the subscriber orgs?

  • http://profile.typepad.com/sher0d Sher0d

    I’ve been trying this out, and it seems to work fine as long as you are doing a query, if you are trying an insert, then weird stuff happens.
    Specifically, the insert seems to succeed (no exception) and I get back an id appropriate for the type of the object inserted, but it seems like no actual real persistent record is saved. Almost like its a unit test.
    Bug?
    @RemoteAction
    global static String createOrDestroyCode(String checkboxValue) {
    //siteCertId + ‘:’ + opportunityCode.Code__c
    Opportunity_Site_Certification_Code__c code = new Opportunity_Site_Certification_Code__c();
    String[] values = checkboxValue.split(‘:’);
    System.debug(values);
    if (values[2] == ‘null’)
    {
    code.Code__c = values[1];
    code.Oppty_Site_Cert_Standard_Program__c = values[0];
    try {
    insert code;
    values[2] = code.id;
    } catch (DmlException e) {
    values[2] = ‘EXCEPTION’;
    }
    }
    return values[0] + ‘:’ + values[1] + ‘:’ + values[2];
    }

  • KC

    This new feature seems promising. Two questions:
    1) Is the performance of this new JavaScript Remoting feature better than the existing ajax toolkit?
    2) Any plans to support sobjects or arrays of sobjects as parameters?

  • KC

    Another question: Can arrays be returned? e.g. array of strings or array of sobjects.
    My simple test seems to only work when a single string is returned.

  • Josh

    1) Is the performance of this new JavaScript Remoting feature better than the existing ajax toolkit?
    Should be faster, since it’s JSON against the server, not XML as a SOAP call.
    2) Any plans to support sobjects or arrays of sobjects as parameters?
    I’ll inquire – there should be an update blog post for this in the near future, especially when some of the DML issues are cleared up.
    And if I’m reading the third point correctly, the example above is returning an array of objects. Maybe it’s something more specific? Feel free to email me directly if that might help.

  • KC

    Josh, thanks for the info. Can an object containing a string property and an array (objects of a custom class) as a property be returned?

  • Josh

    So you want to send over a Apex object with both a string and an array of objects, and send that over as a response? Or perhaps I’m confused.
    Might be easier to send me a follow up email, and I can see if I can send back a working example.

    • Kyler Nunery

      I am trying to do something similar. I want to send back an instance of a custom apex (not custom object) class… “Address”. Javascript receives an object, but when I try to access property accesors like myAddress.City it says undefined. Can you comment more on the serialization/deserialization, as that might be where the problem is?

      • http://twitter.com/joshbirk Josh Birk

        What’s the object structure like? I had someone show me a demo where they were using a custom Apex class with a string and a double. Can you debug the result and error objects?

  • http://www.CyanGate.com Logan

    Will this work with Professional Orgs as they did not have access to API before.
    Is this a way to bypass that limitation?

  • http://tophtml.blogspot.com TopHTML

    Great post. I studied it now and I get so many useful things here. Thanks…

  • Mike

    Trying this code, I get a java.net.MalformedURLException in the server response. No more information than that.

  • Hal Saleh

    Fantastic resource! JSRemoting Rocks!

  • phaniraj nadiger

    Thanks for solving my biggest probs

  • Thomas Gagne

    Has anyone discovered if there’s a limit to the size of the JSON object returned? I have an instance where I suspect the return is being null’ed-out if it’s too big, but there’s no exception to be found in the logs.

  • sreejith nair

    as far as i understood, the javascript method contactSearch() needs to be called through some event, like a button click or something… but in my senario, i want the PayPal IPN response to call this method. to make it clear, the IPN response pings a script code whose URL is known to it. so rather than this script getting called on some event on the page(like button click or something) i want to call this javascript through IPN. help me out.