Reputation: 925
I'm trying to create a family Tree using JSON data then iterating over that and displaying each member of the family with relevant details on the web page. The problem seems to be that the data is getting mixed up somewhere. For example, where I set that date that a family member died, it's getting mixed up and passed out onto the web page under the wrong person.
Here is my JS code:
function family(data) {
var xhttp, jsonData, parsedData;
// check that we have access to XMLHttpRequest
if(window.XMLHttpRequest) {
xhttp = new XMLHttpRequest();
} else {
// IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// get the data returned from the request...
jsonData = this.responseText;
// ...and parse it
parsedData = JSON.parse(jsonData);
displayData(parsedData);
}
};
xhttp.open("GET", data, true);
xhttp.send();
}
function displayData(data) {
var div, name, dob, died, spouse, mother, father;
data.forEach(function(member){
div = document.createElement('div');
div.id = member.name.split(' ').join('-').toLowerCase();
name = document.createElement('h1');
name.innerText = member.name;
dob = document.createElement('p');
dob.innerText = member.dob;
if(member.died !== null) {
died = document.createElement('p');
died.innerText = member.died;
div.appendChild(died);
}
if(member.spouse !== null) {
spouse = document.createElement('p');
spouse.innerText = member.spouse;
}
if(member.parents !== null) {
mother = document.createElement('p');
mother.innerText = member["parents"]["mother"];
father = document.createElement('p');
father.innerText = member["parents"]["father"];
div.appendChild(mother);
div.appendChild(father);
}
div.appendChild(name);
div.appendChild(dob);
div.appendChild(spouse);
var scriptTag = document.getElementsByTagName('script')[0];
document.body.insertBefore(div, scriptTag);
});
}
family('family.json');
And my JSON data looks like this:
[
{
"name": "John Smith",
"gender": "male",
"dob": "12 August 1940",
"died": null,
"parents": null,
"spouse": "Betty Smith"
},
{
"name": "Betty Smith",
"gender": "male",
"dob": "23 September 1937",
"died": null,
"parents": null,
"spouse": "John Smith"
},
{
"name": "Joe Smith",
"gender": "male",
"dob": "14 August 1960",
"died": "20 November 2004",
"parents": {
"mother": "Betty Smith",
"father": "John Smith"
},
"spouse": null
}
]
Is there a better way to structure the JSON? More importantly, what am I doing wrong that's causing the the wrong details to be applied? My guess is it's either a) because my for in loop doesn't include child objects, or that it has something to do with instances, though I doubt that latter is the real reason. Just a bit overwhelmed at this point! Any help would be appreciated. Cheers
Upvotes: 0
Views: 68
Reputation: 31692
You have the order wrong (for example: if a person is dead, the date of death will be printed before the name (which is a h1
which will be confusing because it will look like the date of death belongs to the previous person).
You'll have to append the element just after they were created (where the /********/
) like:
div = document.createElement('div');
div.id = member.name.split(' ').join('-').toLowerCase();
name = document.createElement('h1');
name.innerText = member.name;
/********************/
div.appendChild(name);
dob = document.createElement('p');
dob.innerText = member.dob;
/*******************/
div.appendChild(dob);
if(member.died !== null) {
died = document.createElement('p');
died.innerText = member.died;
div.appendChild(died);
}
if(member.spouse !== null) {
spouse = document.createElement('p');
spouse.innerText = member.spouse;
/*****************/
div.append(spouse);
}
if(member.parents !== null) {
mother = document.createElement('p');
mother.innerText = member["parents"]["mother"];
father = document.createElement('p');
father.innerText = member["parents"]["father"];
div.appendChild(mother);
div.appendChild(father);
}
You wasn't even checking if the spouse exists before appending it which if there wasn't one it will append the spouse of the previous person.
And for clarity try to add a string before the value of the property, something like:
died.innerText = "Died: " + member.died;
//...
mother.innerText = "Mother: " + member["parents"]["mother"];
Upvotes: 1
Reputation: 15893
You separated creating and appending of name
, dob
and spouse
- that's your problem.
Add line
name = dob = died = spouse = mother = father = null;
as the first line inside forEach
- and the code will tell you.
function displayData(data) {
var div, name, dob, died, spouse, mother, father;
data.forEach(function(member){
name = dob = died = spouse = mother = father = null;
div = document.createElement('div');
div.id = member.name.split(' ').join('-').toLowerCase();
name = document.createElement('h1');
name.innerText = member.name;
//console.log("append name");
div.appendChild(name);
dob = document.createElement('p');
dob.innerText = "Born: " + member.dob;
//console.log("append dob");
div.appendChild(dob);
if(member.died !== null) {
died = document.createElement('p');
died.innerText = "Died: " + member.died;
//console.log("append died");
div.appendChild(died);
}
if(member.spouse !== null) {
spouse = document.createElement('p');
spouse.innerText = "Spouse: " + member.spouse;
//console.log("append spouse");
div.appendChild(spouse);
}
if(member.parents !== null) {
mother = document.createElement('p');
mother.innerText = "Mother: " + member["parents"]["mother"];
father = document.createElement('p');
father.innerText = "Father: " + member["parents"]["father"];
//console.log("append mother");
div.appendChild(mother);
//console.log("append father");
div.appendChild(father);
}
document.body.append(div);
});
}
var testData = [
{
"name": "John Smith",
"gender": "male",
"dob": "12 August 1940",
"died": null,
"parents": null,
"spouse": "Betty Smith"
},
{
"name": "Betty Smith",
"gender": "female",
"dob": "23 September 1937",
"died": null,
"parents": null,
"spouse": "John Smith"
},
{
"name": "Joe Smith",
"gender": "male",
"dob": "14 August 1960",
"died": "20 November 2004",
"parents": {
"mother": "Betty Smith",
"father": "John Smith"
},
"spouse": null
}
];
displayData(testData);
Upvotes: 2