Search code examples
javascriptpromiseasync-awaitfetchappendchild

App stops working when use async/await with promise and appendChild


I'm trying to understand JS better and deeper, to improve my skills. So, I wrote a demo app that adds JS, CSS and creates DOM elements after loading HTML-document. I also added async/await and promise. When I wait my promise to be resolved (line 31 in JSFiddle code), the app stops working.

It looks like I don't understand something, but I don't know what exactly and how to find the direction, what and how to improve. So, I need your advice.

Here is the fiddle:

http://jsfiddle.net/k4z86nw3/9/

Now it works, but, as I already mentioned, if you uncomment line 31,

(await wait)();

it will stop working.


Solution

  • As it is demonstrated on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise, it needed to call the resolve function inside the promise.

    'use strict';
    
    function initAnimation() {
      (new WOW()).init();
    }
    
    function addCSS() {
      let cssStyleSheet = document.createElement('link');
      cssStyleSheet.rel = 'stylesheet';
      cssStyleSheet.href = 'https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.7.0/animate.min.css';
      document.head.appendChild(cssStyleSheet);
    }
    
    async function addWOW() {
      let wowScriptJS = document.createElement('script');
      wowScriptJS.src = 'https://cdnjs.cloudflare.com/ajax/libs/wow/1.1.2/wow.min.js';
      wowScriptJS.onload = initAnimation;
      document.body.appendChild(wowScriptJS);
    }
    
    (async function run() {
    
      let res = await fetch('https://dl.dropboxusercontent.com/s/i6ckrkzscn6uuhq/data.json');
    
      addCSS();
      addWOW();
    
      let wait = new Promise((resolve, reject) => {
        setTimeout(() => {
          console.log('Already waited N sec.');
          resolve();
        }, 1000);
      });
    
      await wait; // <<< === IF YOU UNCOMMENT THIS LINE, APP WILL STOP WORKING
    
      let jsonData = await res.json();
      let sections = jsonData.sections;
    
      function addNewChildToParentDOMElement({
        childDOMElementName,
        cssClasses,
        innerHTML,
        src,
        parentDOMNode
      }) {
        let childDOMElement = document.createElement(childDOMElementName);
        if (cssClasses) {
          childDOMElement.classList.add(...cssClasses);
        }
        if (innerHTML) {
          childDOMElement.innerHTML = innerHTML;
        }
        if (src) {
          childDOMElement.src = src;
        }
        parentDOMNode.appendChild(childDOMElement);
      }
    
      for (let i = 0; i < sections.length; i++) {
        console.warn('i==', i);
        let newDOMItem = document.createElement('div');
    
        addNewChildToParentDOMElement({
          childDOMElementName: 'h2',
          cssClasses: ['text-centered'],
          innerHTML: sections[i].title,
          parentDOMNode: newDOMItem
        });
    
        addNewChildToParentDOMElement({
          childDOMElementName: 'p',
          cssClasses: ['text-centered', 'wow', 'bounceInUp'],
          innerHTML: sections[i].desc,
          parentDOMNode: newDOMItem
        });
    
    
        let div = document.createElement('div');
        div.classList.add('img-centered');
        div.classList.add('wow');
        div.classList.add('flipInX');
    
        addNewChildToParentDOMElement({
          childDOMElementName: 'img',
          src: sections[i].imgURL,
          parentDOMNode: div
        });
    
        newDOMItem.appendChild(div);
    
        document.body.appendChild(newDOMItem);
      }
    
    })();
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>aj_test</title>
      <style>
        .text-centered {
          text-align: center;
        }
        
        .img-centered {
          text-align: center;
        }
      </style>
    </head>
    
    <body>
    </body>
    
    </html>