I’m starting to learn ajax and could use some help. I’m pulling data through API and I am getting a response in the console but can’t figure out how to properly target the response so I can fill a table.
How do I target the scores in the JSON response so the scores are put beneath every category? The scores are dynamic.
Form:
<form class="pagespeed">
<input type="text" id="url" placeholder="Enter webpage URL" />
<input type="button" value="Analyse Webpage" onclick="loadAnalysis()" />
<div id="analysisTable"></div>
</form>
AJAX function:
function loadAnalysis() {
var xhttp = new XMLHttpRequest();
var url = document.getElementById("url").value;
if (url == "") {
alert("Please enter URL");
return;
}
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var data = this.responseText;
var jsonResponse = JSON.parse(data);
console.log(jsonResponse["lighthouseResult"]);
var table = document.createElement('table');
table.setAttribute('class', 'result');
var properties = ['performance', 'accessibility', 'best-practices', 'seo', 'pwa'];
var capitalize = function(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
var tr = document.createElement('tr');
for (var i = 0; i < properties.length; i++) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(capitalize(properties[i])));
tr.appendChild(th);
}
table.appendChild(tr);
var tr, row;
console.log("jsonResponse", jsonResponse);
for (var r = 0; r < jsonResponse["lighthouseResult"].categories.length; r++) {
tr = document.createElement('tr');
row = jsonResponse["lighthouseResult"].categories[r];
for (var i = 0; i < properties.length; i++) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(row[properties[i]]));
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById('analysisTable').appendChild(table);
}
};
xhttp.open("GET", "https://www.googleapis.com/pagespeedonline/v5/runPagespeed?url=" + encodeURIComponent(url) + "&key=AIzaSyDSNxhf0capOwppqlg9wZJUvzBewxf6mHU&strategy=mobile", true);
xhttp.send();
}
JSON response example:
{"lighthouseResult":{"categories":{"performance":{"score":1.0},"accessibility":{"score":0.9},"best-practices":{"score":0.92},"seo":{"score":0.7},"pwa":{"score":0.54}}}}
Sample:
//var data = this.responseText; //original
var data = '{"lighthouseResult":{"categories":{"performance":{"score":1.0},"accessibility":{"score":0.9},"best-practices":{"score":0.92},"seo":{"score":0.7},"pwa":{"score":0.54}}}}'
var jsonResponse = JSON.parse(data);
console.log(jsonResponse["lighthouseResult"]);
var table = document.createElement('table');
table.setAttribute('class', 'result');
var properties = ['performance', 'accessibility', 'best-practices', 'seo', 'pwa'];
var capitalize = function(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
var tr = document.createElement('tr');
for (var i = 0; i < properties.length; i++) {
var th = document.createElement('th');
th.appendChild(document.createTextNode(capitalize(properties[i])));
tr.appendChild(th);
}
table.appendChild(tr);
var tr, row;
console.log("jsonResponse", jsonResponse);
for (var r = 0; r < jsonResponse["lighthouseResult"].categories.length; r++) {
tr = document.createElement('tr');
row = jsonResponse["lighthouseResult"].categories[r];
for (var i = 0; i < properties.length; i++) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(row[properties[i]]));
tr.appendChild(td);
}
table.appendChild(tr);
}
document.getElementById('analysisTable').appendChild(table);
<div id="analysisTable"></div>
2
Answers
It looks like you’re forgetting about the
score
property each section of your data has.should be
lighthouse.categories.length
will be 0 because it addresses an object not an array.Use
Object.keys
to iterate over the keys.See the example underneath.
We use
Object.keys
to iterate over every entry of category. Then thelength
returns one row.At last we target the property:
jsonResponse["lighthouseResult"][categories[r]];
and append thescore
property.With Object.keys there is room for code improvement. Look at this cleaned up example: