Find your content:

Search form

You are here

JavaScript Remoting on Standard Page Layout

 
Share

I have a couple of JavaScript remoting functions used to count records and to display that count to the end user. The JavaScript remoting functions are on a Visualforce page, and the Visualforce page is embedded on a page layout of a custom object.

What is happening is that the javascipt remoting functions are supposed to count the number of records available after filters are set. However intermittently the user will receive the error “Unable to connect to server”.

I have a couple of JavaScript remoting functions are working against a custom object, and there are other remoting functions working on the Task object. These functions are doing nothing more than counting records in the system. The JavaScript remoting function counting records on the Task object are working more constistently than the JavaScript remoting functions counting records on the custom object.

I’m worried that this error may a result of the fact that the custom object is not indexed, and therefore counting records for that object may require more time than what is allowed for JavaScript remoting functions. If this is the case, should I do something to get the custom object indexed?

Also, I’m concerned that the “Unable to connect to server” error is a known bug, from what I have gathered on the forums. If this is the case is there a known fix?

Below is an example of the JavaScript remoting function on the Task object, to count the number of task records for the given parameters. This function is failing some of the time, mostly in the morning when first logging into the system.

//Javascript Remoting Function
controllerExampleCounter.asyncReviewedClosed(String("{!Example_Custom_Setting_Validation__c.OwnerId}"), function(result, event) {
    if (event.status) {
        $("#reviewedClosed").text(addCommas(result));
    } else if (event.type === "exception") {
        $("#reviewedClosed").text("Error: " + event.message);
    } else {
        $("#reviewedClosed").text("Error: " + event.message);
    }
}, {escape:true});

//Apex Function
@RemoteAction @ReadOnly
global static Integer asyncReviewedClosed(String owner_id)
{
    Integer incomplete = 0;

    try{
        incomplete = [Select count() 
            From Task 
            Where RecordType.Name = 'Qualification Task' 
                And CreatedById = :String.escapeSingleQuotes(owner_id) 
                And IsClosed = true 
                And CreatedDate = THIS_YEAR];
    } catch(Exception e) {
    }

    return incomplete;
}

Attribution to: Tony H.

Possible Suggestion/Solution #1

Antonio, is the call to the JS after the DOM is ready or just whenever it's loaded.

It's possible that the rest of the JS hasn't loaded when you attempt to invoke this function.

Also have you opened the debug log to see if the function is even being hit when the iFrame (the way VF loads pages inside of other page layouts) is being loaded.

Also, not sure about the JS, I think it's correct but it's possible that you should simplify the JS invoking the remote action (I'm using: $.ready() in jQuery):

$(function(){
    controllerExampleCounter.asyncReviewedClosed('{!Example_Custom_Setting_Validation__c.OwnerId}',function(){ ... });
});
}

Attribution to: jordan.baucke

Possible Suggestion/Solution #2

It sounds like your Apex method is taking longer than the JavaScript Remoting timeout, which is 30 seconds.

To my knowledge JavaScript Remoting still doesn't allow you to specify a custom timeout. I researched this pretty heavily back in January or so and that was the answer I received.

I do have an idea on the IdeaExchange to allow user customizable timeouts. Please take a moment and vote that idea up: https://sites.secure.force.com/success/ideaView?id=08730000000gLukAAE

My suggestion for fixing your issue in the meantime would be to switch to executing this method as a web service call and use the AJAX toolkit to call the web service in your VisualForce page.

Here's some example code to add to a VisualForce page to call an Apex web service with the AJAX Toolkit. You'll need to define your method with the webService annotation and it will need to be in a global class.

<!-- Set the session ID for the AJAX toolkit to use automatically -->
<script type="text/javascript">
    var __sfdcSessionId = '{!GETSESSIONID()}';
</script>
<!-- Include the AJAX Toolkit -->
<script  src="/soap/ajax/25.0/connection.js" type="text/javascript"></script>
<script  src="/soap/ajax/25.0/apex.js" type="text/javascript"/></script>
<script  type="text/javascript">
    // Execute the Apex web service.
    sforce.apex.execute( '<namespace>/<class>',
        '<method name>',
        {ownerId: '<ownerId>'},
        {onSuccess: displayCount, onFailure: errorHandler, timeout: 300000 //timeout in ms}
        );

    function displayCount( result )
    {
        // Add your code here to update/display your count.
    }

    function errorHandler( error )
    {
        // Handle errors.
    }
</script>

Information on the webService annotation can be found here: http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_web_services_methods_considerations.htm#kanchor587

Here's a simpler method for querying the count directly via the AJAX Toolkit without relying on a webService method.

<apex:page >
<!-- Set the session ID for the AJAX toolkit to use automatically -->
<script type="text/javascript">
    var __sfdcSessionId = '{!GETSESSIONID()}';
</script>
<!-- Include the AJAX Toolkit -->
<script src="/soap/ajax/25.0/connection.js" type="text/javascript"></script>
<script src="/soap/ajax/25.0/apex.js" type="text/javascript"></script>
<!-- jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript">
    $().ready( function() {
            queryCount();
        });

    function queryCount()
    {
        // Execute the Apex web service.
        sforce.connection.query(
            "SELECT Count() FROM Lead",
            {
                onSuccess: handleCount,
                onFailure: queryFailed, 
                timeout: 300000 // Set timeout to 5 minutes
            });
    }

    function handleCount( result )
    {
        // Add your code here to update/display your count.
        $( '#output' ).append( result.size );

    }

    function queryFailed( error )
    {
        // Handle errors.
        $( '#output' ).append( error );
    }
</script>
<div id="output">
</div>
</apex:page>

You might also consider creating a custom object to aggregate these totals on a nightly, hourly or semi-hourly basis by executing a scheduled Batch Apex job. You could then quickly query that table to display the requested data.


Attribution to: E.J. Wilburn

Possible Suggestion/Solution #3

The following is not officially support, so be careful, and is applied to all requests. Also, be aware that Salesforce.com's general HTTP request timeout may come into play.

<script>
_Visualforce.Ajax.timeout=120000;
...
</script>

And, BTW, Visualforce Remoting is a popular feature of Visualforce.


Attribution to: cwall
This content is remixed from stackoverflow or stackexchange. Please visit https://salesforce.stackexchange.com/questions/1207

My Block Status

My Block Content