0

I'm building all of my pages using the SPA (single page app) approach lately. I have typically been following this general model for doing so:

My page:

<apex:page docType="html-5.0" showHeader="true" sideBar="true" standardController="TheStandardController" extensions="TheExtension">
    <script>
        window.__APEX_VARS__ = {
            //...throw any one-off merge fields in this object literal I might need in my app, since in a resource file I can't use merge fields.
            //I'm usually throwing this in constants.js and just doing export const APEX = window.__APEX_VARS__; so anywhere in my react components I can just import {APEX} from '../lib/constants';
        };
    </script>
<div id="ContainerForMyApp"></div>

<script src="{!URLFOR($Resource.TheApp)}"></script>
</apex:page>

This works perfectly fine, but I've been struggling with identifying the cleanest way to get any data or config from "TheExtension.cls" (my apex controller extension). I've tried the following approaches:

  1. Remote Actions These work just fine, but I'm coming across a few caveats. Has anyone experienced these? If so, what was your solution?

Let's say my "MyApp.Resource" is JavaScript, and I'm going to include a bit of React since I'm working with that right now. Generally, the MyApp script might look something like this:

import React, {Component} from 'react'; window.React = React;
import ReactDOM from 'react-dom';

Visualforce.remoting.Manager.invokeAction("TheExtension.TheMethod", ...args, (result, event) => {
   ReactDOM.render(
       <App
          props={result} //You get the idea, stuff from the result of the remote action is needed to render the "App" component.
       />,
       document.getElementById("ContainerForMyApp")
   );
});

There are a few problems I've noticed with this approach: sometimes "Visualforce" is undefined on page load. Other times, it isn't and I'm not sure the reason for that. The second issue is the obvious one, that the "App" component won't be rendered until the async remote action returns a result of some kind.

Has anyone done this and used redux or another similar state management architecture to render the page, and then have the data and config populate once it's retrieved from the server? Is there an alternative to using remote actions that I may have overlooked?

1
  • Just to add on to this a bit, I'd like to clarify my point about Visualforce being undefined on page load. It seems like this only happens when i'm in development and the next time I refresh/load the page after I save a new change to the resource file to my sandbox. Anyone have any idea why this is? Is this just a caching issue, and won't happen in production? Jan 25 '16 at 19:33
0

Given this is 6 months old as I write this, you've probably solved this by now, but, perhaps using <apex:includeScript loadOnReady="true" value="{!URLFOR($Resource.TheApp)}" /> to load your app would resolve the problems with "Visualforce" sometimes being undefined on page load.

1
  • Thanks for your feedback! Sorry for the delayed response. I had found the cause, but no real explanation. I answered my own question above. Aug 19 '16 at 14:28
0

I have found a partial answer to this. When the visualforce page in question contains the <apex:detail> component and loads a script which invokes a RemoteAction function, Visualforce will be undefined on the first page load after each recompilation of the Static Resource. I don't have an explanation for this, but if you remove the detail component, recompile the resource, and then load the page it's totally fine.

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.