You need to sign in to do that
Don't have an account?
JavaScript Remoting calls not working from managed package
JS Remoting works fine in a managed package within Visualforce pages.
However, when moving the @RemoteAction to an extension for an inline VF page, it stops working. Example code taken directly from this HOWTO article.
The remoting action silently fails to console log with the following error messages:
Controller not found for 'IO.LineItemRemotingExtension' VFRemote.js:114 Unable to invoke action 'IO.LineItemRemotingExtension.getAccountRemote': no controller and/or function found VFRemote.js:114 $VFRM.Util.error VFRemote.js:114 $VFRM.ProviderManager.VFExt3.extend.invokeAction VFRemote.js:134 getRemoteAccount servlet.Integration:19 onclick
Visualforce Page (inline)
<apex:page showHeader="false" sidebar="false" standardController="Order__c" extensions="LineItemRemotingExtension" standardstylesheets="true"> <head> <script type="text/javascript"> function getRemoteAccount() { var accountName = document.getElementById('acctSearch').value; Visualforce.remoting.Manager.invokeAction( '{!$RemoteAction.LineItemRemotingExtension.getAccountRemote}', accountName, function(result, event){ if (event.status) { // Get DOM IDs for HTML and Visualforce elements like this document.getElementById('remoteAcctId').innerHTML = result.Id document.getElementById( "{!$Component.block.blockSection.secondItem.acctType}" ).innerHTML = result.Type; } else if (event.type === 'exception') { document.getElementById("responseErrors").innerHTML = event.message + "<br/>\n<pre>" + event.where + "</pre>"; } else { document.getElementById("responseErrors").innerHTML = event.message; } }, {escape: true} ); } </script> </head> <input id="acctSearch" type="text"/> <button onclick="getRemoteAccount()">Get Account</button> <div id="responseErrors"></div> <apex:pageBlock id="block"> <apex:pageBlockSection id="blockSection" columns="2"> <apex:pageBlockSectionItem id="firstItem"> <span id="remoteAcctId"/> </apex:pageBlockSectionItem> <apex:pageBlockSectionItem id="secondItem"> <apex:outputText id="acctType"/> </apex:pageBlockSectionItem> </apex:pageBlockSection> </apex:pageBlock>
Apex Controller Extension
global with sharing class LineItemRemotingExtension { private final Order__c m_order; public LineItemRemotingExtension(ApexPages.StandardController stdController) { String oid = stdController.getRecord().Id; this.m_order = Database.query('SELECT ' + Order.SFIELDS + ' FROM Order__c WHERE Id=:oid LIMIT 1'); } @RemoteAction global static Account getAccountRemote(String accountName) { return [SELECT Id, Name, Phone, Type, NumberOfEmployees FROM Account WHERE Name = :accountName]; } }
Tried replacing the call to {!$RemoteAction.LineItemRemotingExtension.getAccountRemote} with just plain
RemoteAction.LineItemRemotingExtension.getAccountRemote
-and-
IO.RemoteAction.LineItemRemotingExtension.getAccountRemote
But neither option works. It doesn't appear to be a managed package namespace issue, but more like a controller extension related anomoly.
Any one else encountered this, or have thoughts/suggestions?
Thanks!
-Mike
Edit: Per Josh's suggestion, I've tried binding directly to the controller extension name/method, bypassing invokeMethod. This this also does not work, throwing different exceptions with and without namespace prefix. Examples below:
<script type="text/javascript"> function getRemoteAccount() { var accountName = document.getElementById('acctSearch').value; LineItemRemotingExtension.getAccountRemote(accountName, function(result, event){ if (event.status) { alert("success"); } else if (event.type === 'exception') { alert(event.message); } else { alert(event.message); } }, {escape: true} ); } </script>
Exception: Uncaught ReferenceError: LineItemRemotingExtension is not defined
With namespace prefix:
IO.LineItemRemotingExtension.getAccountRemote
Exception: Uncaught TypeError: Cannot call method 'getAccountRemote' of undefined
FIXED / RESOLVED
TL;DR: This was discovered to be a javascript namespace conflict bug. Not related to the Salesforce remoting manager.
Details:
The Remoting manager generated a javascript namespace from the managed package prefix; in this case "IO". The controller methods are then available with the syntax namespace.controller.method.
The conflict occured when an imported static resource JS library contained the same namespace prefix.
Resolution:
Update the JS static resource with a non conflicting namespace.
All Answers
Definitely avoid talking to the remote manager directly, even if it works now it's possible it will fail in the future if the manager implementation changes.
When I pull just a simple controller and the remote logic into a DE org with no managed package, it works as expected. As a guess, did you try:
IO_LineItemRemotingExtension.getAccountRemote
I haven't used Remoting in many managed packages, but that might fit the namespace requirement. The abstracted JavaScript object for the extension remote should be visible within the console, so a quick way to see the function is available is to simply log it. For instance, in an unmanaged package:
console.log(LineItemRemotingExtension);
Displays the expected function.
FIXED / RESOLVED
TL;DR: This was discovered to be a javascript namespace conflict bug. Not related to the Salesforce remoting manager.
Details:
The Remoting manager generated a javascript namespace from the managed package prefix; in this case "IO". The controller methods are then available with the syntax namespace.controller.method.
The conflict occured when an imported static resource JS library contained the same namespace prefix.
Resolution:
Update the JS static resource with a non conflicting namespace.