Reputation: 5455
We have an Ember (3.5) application. For technical reasons we need environment variables to be set on page load, as opposed to build time. We're trying to set them in index.html
the following way:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>App</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for "head"}}
<script type="application/javascript">
// Object.assign polyfill
Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
window.env = {};
var request = new XMLHttpRequest();
request.open('GET', '/api/frontend_settings', true);
request.send(null);
request.addEventListener('readystatechange', () => {
if (request.status === 200) {
if (request.readyState === 4) {
Object.assign(window.env, JSON.parse(request.response).settings);
}
}
}, false);
</script>
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/app-frontend.css">
{{content-for "head-footer"}}
</head>
<body>
<script integrity="" src="{{rootURL}}assets/vendor.js"></script>
<script integrity="" src="{{rootURL}}assets/app-frontend.js"></script>
</body>
</html>
We added a script which makes a request to some endpoint (/api/frontend_env_vars
) in the snippet. This endpoint responds with a JSON with the key-values of environment variables which we then assign to window.env
.
The problem we have is that sometimes Ember scripts load before the variables have been assigned (since we do a request that takes some time to complete), which makes the application crash.
We tried the following alteration to the script, but it didn't work (the error was different, though):
<script type="application/javascript">
// Object.assign polyfill
Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
window.env = {};
var request = new XMLHttpRequest();
request.open('GET', '/api/frontend_env_vars', true);
request.send(null);
function loadScript(src) {
const script = document.createElement('script');
script.src = src;
document.body.append(script);
}
request.addEventListener('readystatechange', () => {
if (request.status === 200) {
if (request.readyState === 4) {
Object.assign(window.env, JSON.parse(request.response).settings);
loadScript('assets/vendor.js');
loadScript('assets/app-frontend.js');
}
}
}, false);
</script>
Upvotes: 0
Views: 571
Reputation: 2474
We accomplish this using ember-cli-server-variables
Which allows you to define variables in index.html
<html>
<head>
<meta name='your-app-token' content='example:app:token'>
<meta name='your-app-user-location' content='Denver'>
<meta name='your-app-json-data' content='{"foo":"bar"}'>
</head>
</html>
and then access them from the application.
We build our index.html
on the server with the needed variables to there is no async needed to fetch them.
Upvotes: 1