5

I'm working with a page that is a container for a single page app.

<apex:page>
    <div id="root"></div>
    <script src="{!URLFOR($Resource.javascriptResource)}"></script>
</apex:page>

In the beginning of my resource, I'm invoking a @RemoteAction:

Visualforce.remoting.Manager.invokeAction("Controller.getOptions", ...args, function(result, event) {
    //do stuff with the result.
});

I've noticed that during development, if I load the page, modify the resource and save it to server, and then reload the page, the Visualforce global is undefined. If I then reload once again, it is properly defined. Does anyone know why? Does this have any potential to affect users in production or would this only occur in development as I described?

3
  • I think this could result in unpredictable behavior as not everything is loaded and ready when your JS is executed . Have you tried using Action in page tag? Mar 2 '16 at 15:43
  • The purpose of the remote action is to provide data from the server to the client to render or use in logic contained in the static resource. I was under the understanding that a page action wouldn't help there. Mar 2 '16 at 18:28
  • Please see related post in which I answered my own question: salesforce.stackexchange.com/questions/106650/… Aug 19 '16 at 14:29
3

I think it is perfectly fine practice to use @RemoteAction to load your application, but you should not count on variables like Visualforce or any merge fields to work from within a Static Resource. They are easier if you reference the method this way (you do not need any inheritance model to make such a reference). What I have done in the past is load the RemoteAction into an object I can then pass to my application. With angular, for instance, I can do:

(function (a) {
    "use strict";
    a.module("myApp", []);
    a.constant("mergeValues", {
        "myRemoteAction": MyController.action
    };
})(angular)

There are many ways you can pass your action to your application, and this is just one example. The main takeaway is that you should pass the function. Another option if you are not using any framework another option may be to create a namespace.

(function (w) {
    "use strict";
    w.myNamespace = w.myNamespace || {}
    w.myNamespace.action = MyController.action
    Object.freeze(w.myNamespace);
})(window);

Then in your static resource, you can do:

w.myNamespace.action(params, callback);
3
  • Thanks! I've played with this in the past, and just added the change to my resource, but I get the same result. How is relying upon the global for your controller different than relying on the Visualforce global? I was under the understanding that they both resulted from VFremoting.js loading, and are effectively the same thing but just different syntax. Mar 2 '16 at 18:29
  • @MattThomas I'm not sure what you're trying to differentiate. The key difference that I see is that when you pass them from the VF page itself, they should always be defined, whereas that's not guaranteed in your resource. In terms of using Visualforce.remoting.Manager, you can't use it to pass one specific action because it takes the method name as a parameter.
    – Adrian Larson
    Mar 2 '16 at 18:31
  • @MattThomas Were you able to get it working more consistently?
    – Adrian Larson
    Mar 9 '16 at 21:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.