Reputation:
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
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 musiccard
s 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 todata
so it makes more sense. I also renameddiv
tomusiccard
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
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