How to delay execution of javascript function until JSON has loaded
<p>I have a page that chains two API calls, loads the data into <code>first_data</code> and <code>second_data</code> before executing a <code>createPage</code> function (which is several kb of data manipulation and d3.js):</p>
<h3>template.html</h3>
<pre><code>&lt;script src=&quot;createPage.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var first_data, second_data = [], [];

function getFirstData(){
    return new Promise(function(resolve) {
        var xhr = new XMLHttpRequest();
        var url = &quot;/API/my-request?format=json&quot;
        xhr.onreadystatechange = function() {
            if (xhr.readyState == 4 &amp;&amp; xhr.status == 200) {
                first_data = JSON.parse(xhr.responseText);
                resolve('1');
            }
        }
        xhr.open(&quot;GET&quot;, url, true);
        xhr.send();
    });
} //similar function for getSecondData()

getFirstData()
    .then(getSecondData)
    .then(createPage(first_data, second_data));
&lt;/script&gt;
</code></pre>
<p>The trouble is that some of the code that manipulates the data in <code>createPage</code> is showing errors, for example &quot;<code>can't convert undefined to object</code>&quot;. In that particular error's case, it's because I try to do <code>Object.keys(data[0])</code> on some data that should be loaded from the API requests. Some observations:</p>
<ul>
<li>If I inspect the data in the browser dev console, it's all there.</li>
<li>If I just paste the code from the file in the console, the page draws fine.</li>
<li>If I hard-code the initializing arrays etc for the data manipulation part of the code (to get rid of the <code>can't convert undefined</code>, then the page draws but all the graphics indicate that they were populated with no data.</li>
<li>The page loads fine if I put the the JSON data in a .js file and load it as a script just before the createPage.js file at the end of the body.</li>
<li>I inserted a <code>console.log(&quot;starting&quot;)</code> statement at the start and end of <code>createPage()</code>. Looking at the network and js console output when I load, the <code>starting</code> output occurs before the two API GET requests are displayed in the network activity. Is this representative of what's really happening (i.e. can you mix javascript console and network console timing?)</li>
</ul>
<p>So, clearly I don't have access to the data at the point when I need it.</p>
<ul>
<li>Why? Are my <code>Promises</code> incorrect?</li>
<li>How can I fix this?</li>
</ul>