user10639908
user10639908

Reputation:

Moving elements created in JS into another element created in JS

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);
     }
  });
 }

Upvotes: 1

Views: 42

Answers (2)

Andy
Andy

Reputation: 63524

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>

Upvotes: 1

Eric R.
Eric R.

Reputation: 146

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

Upvotes: 0

Related Questions