Skip to content

Instantly share code, notes, and snippets.

@odewahn
Last active August 3, 2020 02:25
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save odewahn/8c72f60ca3ad3c11cda8f4ddb6a49b02 to your computer and use it in GitHub Desktop.
Save odewahn/8c72f60ca3ad3c11cda8f4ddb6a49b02 to your computer and use it in GitHub Desktop.
Loading global environment variables in a single page app (SPA) in react/redux

I was trying to pass config variables from a backend written in Go to a single page app (SPA) written in react. For example, I wanted to set an "Env" flag to dev or prod or control whether you have to log in or not. Here's an example of the /api/config route that supplies this data:

{
    "Auth0ClientDomain": "odewahn.auth0.com", 
    "Auth0ClientID": "gcSxq9GfpUdVWNIvYiOsP7rh1s8u6ftA", 
    "ClientBrowser": "HTTPie", 
    "ClientOS": "darwin", 
    "Env": "dev", 
    "FirstClientLoad": "true", 
    "HomeDir": "/Users/odewahn", 
    "HostCount": 0, 
    "HostFileName": ".launchbot.yml", 
    "LaunchbotEndpoint": "http://launchbot.io", 
    "RequireLogin": true, 
    "UserMode": "free", 
    "Version": "0.1.4", 
    "WelcomeMessageVisible": true, 
    "WelcomeVideoYouTubeID": "xUGwz0A6eKU"
}

This is pretty common thing, and while it's easy in most server side contexts where you can just dump these things right into the page, it took me a while to make it work in the React/Redux single page app world. Although the API supplied the results accurately, the frontend would load and display, and only then load the config information. So, actions I wanted to trigger weren't being set correctly.

I finally figured out a simple workaround: use fetch to wrap the call to ReactDOM.render in a promise chain so that you render the page app only after you're gotten the results back and dispatched the action to load the config values into the state tree:

fetch('/api/config')
  .then( response => {
      return response.json()
  })
  .then( config => {
    store.dispatch(setConfig(config))
  })
  .then( () => {
    ReactDOM.render(
      <Provider store={store}>
        <Router>{routes}</Router>
      </Provider>,
      document.getElementById('app')
    )
  })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment