1

So I have a function that creates a div titled 'musiccard' within the 'content' div and after I have it pull JSON data and use that for the music data. For now it all currently resides in the content div and I was wondering on the best way to move it into the music card which is being created at the same time the data is being pulled.

Here's my js file:

var content = document.getElementById("content");


document.addEventListener("DOMContentLoaded", function() {
  init();
  title();
  headerDescription();
});


 function init() {
  loadJSON(function(response) {
     var json = JSON.parse(response);
     var count = Object.keys(json.musics).length;
     for(var i=0; i<count; i++){

      var div = document.createElement("div");
       div.setAttribute("class", "musiccard");
       content.appendChild(div);

      var h3 = document.createElement("h3");
      h3.textContent = json.musics[i].title;
      content.appendChild(h3);

      var p = document.createElement("p");
      p.setAttribute("class", "albumruntime");
      p.innerHTML = 'Run Time:' + json.musics[i].running_time + 'min';
      content.appendChild(p);

      var p = document.createElement("p");
      p.setAttribute("class", "musicdescription");
      p.innerHTML = json.musics[i].description;
      content.appendChild(p);

       var img = document.createElement("img");
       img.src = json.musics[i].url;
       img.setAttribute("class", "albumart");
       content.appendChild(img);
     }
  });
 }
2
  • Where do you want to put the music cards you've created? You want to move them from <div id="content"> to another div? Commented Nov 26, 2018 at 11:50
  • @Andy At the moment they are in the <div id="content"> but I want all the other information that currently resides in the content div such as the title, image, description to go into the music card div Commented Nov 26, 2018 at 12:00

2 Answers 2

1

Similar to how you added the new musiccard to the content element you can add all those new elements to the musiccard element instead before you add it to content.

Some steps you can follow:

1) Grab the content element.

2) Create a document fragment. This is useful if you're adding updating elements in a loop. Instead of adding all the elements to the DOM you add them to a fragment and add that single fragment to the DOM once the loop is complete. It's more efficient.

3) Create the musiccard element and add all the other new elements to it.

4) At the end of the loop add the musiccard to the fragment

5) After all the musiccards have been added to the fragment, add the fragment to content.

Note: JSON is what is returned from the server. Once you parse it it's no longer JSON. I renamed your json variable to data so it makes more sense. I also renamed div to musiccard so the code is easier to follow.

function loaddata(callback) {
  const json = '{"musics": [{"title": "title1", "running_time": 10, "description": "Note1", "url": "http://bob.com" }]}';
  callback(json);
}

function init() {
  loaddata(function(response) {

    var data = JSON.parse(response);

    var count = Object.keys(data.musics).length;
    
    // grab the content div
    var content = document.getElementById('content');

    // create the fragment
    var frag = document.createDocumentFragment();

    for (var i = 0; i < count; i++) {

      var musiccard = document.createElement("div");
      musiccard.setAttribute("class", "musiccard");

      var h3 = document.createElement("h3");
      h3.textContent = data.musics[i].title;
      
      // add the title to musiccard
      musiccard.appendChild(h3);

      var p = document.createElement("p");
      p.setAttribute("class", "albumruntime");
      p.innerHTML = 'Run Time:' + data.musics[i].running_time + 'min';
      
      // add runtime to musiccard
      musiccard.appendChild(p);

      var p = document.createElement("p");
      p.setAttribute("class", "musicdescription");
      p.innerHTML = data.musics[i].description;
      
      // add description to musiccard
      musiccard.appendChild(p);

      var img = document.createElement("img");
      img.src = data.musics[i].url;
      img.setAttribute("class", "albumart");

      // add img to musiccard
      musiccard.appendChild(img);

      // add completed musiccard to the fragment
      frag.appendChild(musiccard);

    }

    // add the fragment containing all the musiccards
    // to the content div
    content.appendChild(frag);

  });

}

init();
<div id="content"></div>

Sign up to request clarification or add additional context in comments.

Comments

0

Remember that creating the musiccard div at the same time as the data is pulled is inherently synchronous. You want to use an asynchronous function to achieve the desired result, calling back the function creating the div once pulling the data from the json file is complete.

You could, perhaps, create a Promise which pulls the data and then returns the musiccard div, with the data displayed inside of it, passing this result - the response received - into the then() callback.

Here's a really informative article on using Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

1 Comment

The question isn't about synchronous/asynchonous processes. The OP was simply adding new elements to the wrong parent element.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.