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, 2016 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, 2016 at 18:28
  • Please see related post in which I answered my own question: salesforce.stackexchange.com/questions/106650/… Aug 19, 2016 at 14:29

1 Answer 1

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, 2016 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, 2016 at 18:31
  • @MattThomas Were you able to get it working more consistently?
    – Adrian Larson
    Mar 9, 2016 at 21:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .