Search code examples
javascriptappendchilddocumentfragment

Why isn't my appendChild working with createDocumentFragment?


I am trying to append newly created elements to a div, then append the div to a document fragment, but it isn't working as expected. Please help me identify what I am missing.

//array of values to look up
let channels = ["channel1", "channel2", "channel3","channel4","channel5","channel6","channel7","channel8","channel9","channel10","channel11","channel12","channel13","channel14","channel15","channel16"];

//jsonp request function defined
function streamRequest () {

  //identify DOM elements for final appendChild
  let docFrag = document.createDocumentFragment();
  let container = document.getElementById("main-container");

  //create container and elements for the acquired information
  let div = document.createElement("div");
  let image = document.createElement("img");
  let p = document.createElement("p");
  let p1 = document.createElement("p");
  let p2 = document.createElement("p");

  //variables for request responses
  let logo;
  let name;
  let status;
  let game;

  channels.forEach(function channelsRequest(channel){

    $.getJSON("https://api.twitch.tv/kraken/streams/" + channel + "?callback=?", function callback(data) {
      if(data.stream === null){
        status = "Offline"
        game = "Offline"
      } else if (data.stream != null) {
        status = "Online"
        game = data.stream.game
      }
      console.log(channel, status, game);

      $.getJSON("https://api.twitch.tv/kraken/channels/" + channel + "?callback=?",function logoRequest(data) {

        name = data.display_name;

        if(data.logo === null) {
          logo = "http://www.logowik.com/uploads/images/379_twitch.jpg"
        } else if (data.logo != null) {
          logo = data.logo
        }

        //set attributes and inner HTML for new elements
        image.setAttribute("src",logo);
        image.setAttribute("alt","photo of channel's image");
        image.className = "image";
        p.innerHTML = name;
        p.className = "name";
        p1.innerHTML = status;
        p1.className = "status";
        p2.innerHTML = game;
        p2.className = "game";

        //append elements to the div 
        div.appendChild(image)
        div.appendChild(p)
        div.appendChild(p1)

        if(status === "Online"){
          div.appendChild(p2)
        } 

        div.className = "tv-block";
        docFrag.appendChild(div);

        console.log(data, name, logo, docFrag);
      });
    });
  });  
//append final document fragment to the DOM
container.appendChild(docFrag);
};

`

From what I understand, you should be able to append everything to the a div, then append the div to the fragment. When I run the code, nothing is amended to the DOM. I think it may be because of scoping, or the second json request isn't set up properly


Solution

  • I know this answer comes a year later but as I've just completed the same challenge I thought it might make sense to share my solution as I also had the same problem. It looks like creating a new DOM element and appending all generated divs to it and then appending this element to an existing DOM element is faster than using document fragment. So my structure looks like this:

    <body>
        <main>
           <header>
           </header>
        </main>
        <footer>
        </footer>
    </body>
    

    And then I append to the main a div#container created in js and containing all generated divs.

    Here is a link to the completed project.