[SalesForce] Javascript Remoting in Static Resource

Is it possible to call javascript remoting in a static resource?

I'm creating an AngularJS application, and to stick with best practices I would like to put my services in separate files. Theses services are used by angular controllers to get data out of Salesforce.

It works as expected when I define the service in the visual force page as follows:

<script>
      salesCentral.factory('contentData', ['$q', '$rootScope', function($q, $rootScope) {

        return function() {
            var deferred = $q.defer();

            Visualforce.remoting.Manager.invokeAction(
                '{!$RemoteAction.MyJSRemoteController.getContentList}',
                function(result, event) {
                    $rootScope.$apply(function() {
                      if (event.status) {
                        deferred.resolve(result);
                      } else {
                        deferred.reject(event);
                      }
                    })
                },
                { buffer: true, escape: true, timeout: 30000 }
            );

            return deferred.promise;
        }

    }]);
</script>

However, when I include the exact same code from a static resource I get this error

TypeError: Cannot read property 'MyJSRemoteController' of undefined
at Object.$VFRM.Util.getObject (https://cs2.salesforce.com/jslibrary/1383321200000/sfdc/VFRemote.js:119:364)

Does javascript remoting have to be defined directly inside the VisualForce Page?

Best Answer

Javascript remoting can be used within a static resource.

This method fails in a static resource because of the use of the merge field '{!$RemoteAction.MyJSRemoteController.getContentList}' and not because of the use of javascript remoting.

Using the alternate javascript remoting syntax below will work because it is not dependent on a merge field:

MyJSRemoteController.getContentList(function(result, event) {
    //callback stuff
});

Although less elegant, you can also use the following syntax, which is closer to the documented syntax for JS Remoting.:

<script>
      salesCentral.factory('contentData', ['$q', '$rootScope', function($q, $rootScope) {

        return function() {
            var deferred = $q.defer();

            Visualforce.remoting.Manager.invokeAction(
                'MyJSRemoteController.getContentList',
                function(result, event) {
                    $rootScope.$apply(function() {
                      if (event.status) {
                        deferred.resolve(result);
                      } else {
                        deferred.reject(event);
                      }
                    })
                },
                { buffer: true, escape: true, timeout: 30000 }
            );

            return deferred.promise;
        }

    }]);
</script>
Related Topic