Javascript - cannot read property 'x' of undefined - json - javascript

I'm building a table using information from a json object gained from a url and while the table will build and populate a 'cannot read property 'x' of undefined' type error will occur.
The code for getting the json and building the table is:
$.getJSON(url,function(data) {
for (var i = 0; i < 100 || i < data.length; i++) {
tr.append("<td">"+ data[i].Forename + " " + data[i].Surname + "</td>");
tr.append("<td>" + data[i].Workphone + "</td>");
tr.append("<td>" + data[i].id + "</td>");
tr.append("<td>" + data[i].Department + "</td>");
tr.append("<td">" + data[i].Office + "</td>");
tr.append("<td">" + data[i].Floor + "</td>");
tr.append("<td">" + data[i].Room + "</td>");
$('#body').append(tr);
}
}
With a basic example of the json being:
[{
"Forename": "fname",
"Surname": "sname",
"Id": "id",
"Workphone": "phone",
"Department": "department",
"Office": "office",
"Floor": "floor",
"Room": "room"
},
{
"Forename": "fname",
"Surname": "sname",
"Id": "id",
"Workphone": "phone",
"Department": "department",
"Office": "office",
"Floor": "",
"Room": ""
}]
The error is thrown on the first tr.append at data[i].Forename but will occur at the next data[i].property if Forename is removed.
Any help would be appreciated. Thanks.

First of JSON is case sensitive so calling 'id' instead of 'Id' is not going to work.
Secondly you open quotes where not quotes should be. Around the <td>'s.
Third: Where does the variable tr come from? is it defined above this code, otherwise
you should define it somewhere before using it.
Fourth: Do you want to append to the tr to the <body> tag or an element with 'id' #body. You are doing the latter!
Edit: Added the || && suggestion of musefan.
This should work (untested):
$.getJSON(url, function(data) {
for (var i = 0; i < 100 && i < data.length; i++) {
tr.append("<td>" + data[i].Forename + " " + data[i].Surname + "</td>");
tr.append("<td>" + data[i].Workphone + "</td>");
tr.append("<td>" + data[i].Id + "</td>");
tr.append("<td>" + data[i].Department + "</td>");
tr.append("<td>" + data[i].Office + "</td>");
tr.append("<td>" + data[i].Floor + "</td>");
tr.append("<td>" + data[i].Room + "</td>");
$("#body").append(tr);
}
}

Try this one:
for (var i = 0; i < 100 || i < data.length; i++) {
tr.append("<td>"+ data[i].Forename + " " + data[i].Surname + "</td>");
tr.append("<td>" + data[i].Workphone + "</td>");
tr.append("<td>" + data[i].id + "</td>");
tr.append("<td>" + data[i].Department + "</td>");
tr.append("<td">" + data[i].Office + "</td>");
tr.append("<td">" + data[i].Floor + "</td>");
tr.append("<td">" + data[i].Room + "</td>");
$('#body').append(tr);
}`

Related

JQuery tablesorter is not having any effect, what have I done wrong?

I'm very new to jQuery and am trying to use Tablesorter, however it has no effect on my table (styling doesn't change to the tablesorter css, and there is no sorting functionality).
Here is my html:
<html lang="en">
<head>
<meta charset="UTF-8">
<title>FPLHelper</title>
<link rel="stylesheet" href="css/stylesheet.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.2.1/js.cookie.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/js/jquery.tablesorter.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery.tablesorter/2.31.3/css/theme.blue.min.css" rel="stylesheet" />
<script src="js/PlayerList.js"></script>
<script>
$(document).ready(function() {
$("#table-main").tablesorter({ sortList: [[0,0], [1,0]] });
});
</script>
</head>
<body onload="getPlayerList()">
<div class="navigation">
<h1 class="main-heading"><span>FPL</span>Helper</h1>
Home
Account
<a class="open" href="login.html">Login</a>
Register
</div>
<section>
<input type="text" id="playerSearch" onkeyup="tableSearch()" placeholder="Search for a player...">
<div class="tableFixHead">
<table id="table-main" class="tablesorter" cellpadding="0" cellspacing="0" border="0">
<thead>
<tr>
<th>First Name</th>
<th>Second Name</th>
<th>Goals Scored</th>
<th>Goals Assisted</th>
<th>FPL Points</th>
<th>Minutes Played</th>
<th>Goals Against</th>
<th>Creativity Score</th>
<th>Influence Score</th>
<th>Threat Score</th>
<th>Bonus Points</th>
<th>Total BPS</th>
<th>ICT Score</th>
<th>Clean Sheets</th>
<th>Red Cards</th>
<th>Yellow Cards</th>
<th>Selected By</th>
<th>Cost</th>
<th>Position</th>
</tr>
</thead>
<tbody id="table-data">
</tbody>
</table>
</div>
</section>
</body>
</html>
And here is the js to populate the table if that would be helpful to see as well (this is in the PlayerList.js):
function getPlayerList() {
console.log("Invoked getPlayerList()");
const url = "/player/list";
fetch(url, {
method: "GET",
}).then(response => {
return response.json(); //now return that promise to JSON
}).then(response => {
if (response.hasOwnProperty("Error")) {
alert(JSON.stringify(response));// if it does, convert JSON object to string and alert
console.log(response);
} else {
console.log(response);
formatPlayerList(response);
}
});
}
function formatPlayerList(data) {
var tr;
for (var i = 0; i < data.length; i++) {
tr = $("<tr/>");
tr.append("<td>"+ data[i].FirstName + "</a></td>");
tr.append("<td>" + data[i].SecondName + "</td>");
tr.append("<td>" + data[i].Goals + "</td>");
tr.append("<td>" + data[i].Assists + "</td>");
tr.append("<td>" + data[i].FPLPoints + "</td>");
tr.append("<td>" + data[i].MinsPlayed + "</td>");
tr.append("<td>" + data[i].GoalsAgainst + "</td>");
tr.append("<td>" + data[i].Creativity + "</td>");
tr.append("<td>" + data[i].Influence + "</td>");
tr.append("<td>" + data[i].Threat + "</td>");
tr.append("<td>" + data[i].BonusPoints + "</td>");
tr.append("<td>" + data[i].BPSTotal + "</td>");
tr.append("<td>" + data[i].ICTScore + "</td>");
tr.append("<td>" + data[i].CleanSheets + "</td>");
tr.append("<td>" + data[i].RedCards + "</td>");
tr.append("<td>" + data[i].YellowCards + "</td>");
tr.append("<td>" + data[i].SelectedBy + "</td>");
tr.append("<td>" + data[i].BuyCost + "</td>");
tr.append("<td>" + data[i].PlayingPos + "</td>");
$('#table-main').append(tr);
}
isClicked();
}
Sorry if this is something really obvious, and if you need to see any more of my code then just ask. Thanks.
Edit: I have tried without using any of my css at all to see if that was doing anything, but that didn't work either. As per what I answered below, there are no errors etc. in the console.
Welcome to so. tablesorter() by default works only for static table content. All dynamically added tr's must be added into the tablesorter by addRows() method, so your function formatPlayerList() should be changed as follows:
function formatPlayerList(data) {
var tr;
var resort = false, callback = null;
for (var i = 0; i < data.length; i++) {
tr = $("<tr/>");
tr.append("<td>"+ data[i].FirstName + "</a></td>");
tr.append("<td>" + data[i].SecondName + "</td>");
tr.append("<td>" + data[i].Goals + "</td>");
tr.append("<td>" + data[i].Assists + "</td>");
tr.append("<td>" + data[i].FPLPoints + "</td>");
tr.append("<td>" + data[i].MinsPlayed + "</td>");
tr.append("<td>" + data[i].GoalsAgainst + "</td>");
tr.append("<td>" + data[i].Creativity + "</td>");
tr.append("<td>" + data[i].Influence + "</td>");
tr.append("<td>" + data[i].Threat + "</td>");
tr.append("<td>" + data[i].BonusPoints + "</td>");
tr.append("<td>" + data[i].BPSTotal + "</td>");
tr.append("<td>" + data[i].ICTScore + "</td>");
tr.append("<td>" + data[i].CleanSheets + "</td>");
tr.append("<td>" + data[i].RedCards + "</td>");
tr.append("<td>" + data[i].YellowCards + "</td>");
tr.append("<td>" + data[i].SelectedBy + "</td>");
tr.append("<td>" + data[i].BuyCost + "</td>");
tr.append("<td>" + data[i].PlayingPos + "</td>");
//$('#table-main').append(tr);
$('#table-data').append(tr);
$("#table-main").trigger('addRows', [tr, resort, callback]);
}
//
//isClicked();
}
Please take a look on https://mottie.github.io/tablesorter/docs/#methods
I tested the modified function, it works.

Javascript producing random arrays with random numbers in it?

I am doing a simple assignment for class, and am trying to create a table using just Javascript. I have my table perfectly set up, it's just that every other row it shows a random number, and then skips to the next. how can I get rid of the random row?
var table = ["Name", "Turn Average", "Surface Area", "100% Boosting"];
var names = ["Octane", "Dominus", "Breakout", "X-Devil", "Batmobile"];
var turnaverages = [2.18, 2.22, 2.22, 2.21, 2.25];
var surfacearea = [34495, 34529, 32679, 34242, 34365];
var maxboost = [1.967, 2.031, 2.035, 2.014, 2.10];
function info() {
document.write("<table>");
document.write("<tr>");
//these next lines output the table heading (th) tags for the table (this information doesn't repeat in the table)
document.write("<th>Name</th>");
document.write("<th>Turn Average</th>");
document.write("<th>Surface Area</th>");
document.write("<th>100% Boosting</th>");
document.write("</tr>"); //close first table row element
//create a for loop that will last for the number of days in the forecast
for(var i = 0; i < names.length; i++){
document.write("<tr>"); //create a table row
//output each table data tag for the table with information pulled
from the arrays
document.write("<td>" + names[i] + "</td>");
document.write("<td>" + turnaverages[i] + "</td>");
document.write("<td>" + surfacearea[i] + "</td>");
document.write("<td>" + maxboost[i] + "</td>");
document.write("</tr>");
//depending on the description of the weather for the day, change
the image to be representative to that description -- (for
example on a rainy day, show the rainy image)
if ( names[i] === "Dominus" ) {
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
}
else if ( names[i] === "Breakout" ){
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
}
else if ( names[i] === "X-Devil" ){
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
}
else if( names[i] === "Batmobile" ){
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
}
document.write("</tr>"); //close the table row element
}
document.write("</table>"); //close the table element
}
You have
document.write("<td>" + maxboost[i] + "</td>");
document.write("</tr>");
followed immediately by weather tests that attempt to write tds, followed again by another
document.write("</tr>"); //close the table row element
So, you just need to delete the first </tr>, since you don't actually want to close the row yet:
var table = ["Name", "Turn Average", "Surface Area", "100% Boosting"];
var names = ["Octane", "Dominus", "Breakout", "X-Devil", "Batmobile"];
var turnaverages = [2.18, 2.22, 2.22, 2.21, 2.25];
var surfacearea = [34495, 34529, 32679, 34242, 34365];
var maxboost = [1.967, 2.031, 2.035, 2.014, 2.10];
function info() {
document.write("<table>");
document.write("<tr>");
//these next lines output the table heading (th) tags for the table (this
document.write("<th>Name</th>");
document.write("<th>Turn Average</th>");
document.write("<th>Surface Area</th>");
document.write("<th>100% Boosting</th>");
document.write("</tr>"); //close first table row element
//create a for loop that will last for the number of days in the forecast
for (var i = 0; i < names.length; i++) {
document.write("<tr>"); //create a table row
//output each table data tag for the table with information pulled
document.write("<td>" + names[i] + "</td>");
document.write("<td>" + turnaverages[i] + "</td>");
document.write("<td>" + surfacearea[i] + "</td>");
document.write("<td>" + maxboost[i] + "</td>");
//depending on the description of the weather for the day, change
if (names[i] === "Dominus") {
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
} else if (names[i] === "Breakout") {
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
} else if (names[i] === "X-Devil") {
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
} else if (names[i] === "Batmobile") {
document.write("<td>" + turnaverages[i] + surfacearea[i] +
maxboost[i] + "</td>");
}
document.write("</tr>"); //close the table row element
}
document.write("</table>"); //close the table element
}
info();
The 2.22345292.031 and similar numbers are a result of string cocatenation - when you take a string and + to it, you will end up with another string. (not sure what you actually want there instead)

Getting values from an api call

Hi all i have a url with returns values (https://api.sunrise-sunset.org/json?lat=35.857368&lng=14.477653). I would like to get the values of sunset and sunrise. The code I am trying is the following but for some reason nothing is happening. Seems that I cannot access 'second level'
$.getJSON('https://api.sunrise-sunset.org/json?lat=35.857368&lng=14.477653', function (data) {
var tr;
for (var i = 0; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].results[0].sunrise + "</td>");
tr.append("<td>" + data[i].sunset + "</td>");
$('table').append(tr);
}});
Can someone please help me? thanks
Neither the response object nor .results is an array - remove the array indicies.
const tr = $('tr');
$.getJSON('https://api.sunrise-sunset.org/json?lat=35.857368&lng=14.477653', function (data) {
console.log(data.results.sunrise + ' :: ' + data.results.sunset);
tr.append("<td>" + data.results.sunrise + "</td>");
tr.append("<td>" + data.results.sunset + "</td>");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table><tr></tr></table>

for loop is not working inside append function

I want to wrap entire content into single div, it needed for loop inside append function. after wrapping around div in javascript, it's not displaying anything.
here is my code;
$('#postjson').append(
'<div>' + '<div id="' + data[0].id + '">' + '<p>' + '<div id="namediv">' + data[0].FirstName + ' ' + data[0].MiddleName + ' ' + data[0].LastName + '<br/>' + '<span id="locationspan">' + 'xyz' + data[0].Location + '</span>' + '</div>' + '<br/>'
//+'Email:'+data[0].Email+'<br/>'
//+'Mobile:'+data[0].Mobile+'<br/>'
+ '</p>' + '</div>'
// displaying book details
+
for (var i = 1; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].BookNo + "</td>");
tr.append("<td>" + data[i].BookTitle + "</td>");
tr.append("<td>" + data[i].BookGenre + "</td>");
tr.append("<td>" + data[i].BookWriter + "</td>");
tr.append("<td>" + data[i].BookDescription + "</td>");
$('#displaytable').append(tr);
} + '</div>'
);
Perhaps you meant
var $table = $('<table>', {"id:":"displaytable"});
for (var i = 1; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td/>",{"text":data[i].BookNo});
tr.append("<td/>",{"text":data[i].BookTitle});
tr.append("<td/>",{"text":data[i].BookGenre});
tr.append("<td/>",{"text":data[i].BookWriter});
tr.append("<td/>",{"text":data[i].BookDescription});
$table.append(tr);
}
$('#postjson')
.append($('<div />',{"id":"tableDiv"}))
.append($('<div />',{"id":data[0].id}).append($('<div />',{"id":"namediv"}).html(data[0].FirstName + ' ' + data[0].MiddleName + ' ' + data[0].LastName +
.append($table);
Put the loop outside of the append function and finally append the table to the 'container' element, which is specified in the html string
$('#postjson').append(
'<div id="container">' + '<div id="' + data[0].id + '">' + '<p>' + '<div id="namediv">' + data[0].FirstName + ' ' + data[0].MiddleName + ' ' + data[0].LastName + '<br/>' + '<span id="locationspan">' + 'xyz' + data[0].Location + '</span>' + '</div>' + '<br/>' + '</p>' + '</div>')
for (var i = 1; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].BookNo + "</td>");
tr.append("<td>" + data[i].BookTitle + "</td>");
tr.append("<td>" + data[i].BookGenre + "</td>");
tr.append("<td>" + data[i].BookWriter + "</td>");
tr.append("<td>" + data[i].BookDescription + "</td>");
$('#displaytable').append(tr);
}
$("#container").append($('#displaytable'));

Ordering JSON data in a table

I am creating a "leaderboard" page as an external component to a Facebook game.
Basically the app is passing me data through a given JSON response file ('score.json' which contains data objects with three keys: Name, Team, Score), and I am parsing this into an HTML table using the code below:
$(document).ready(function(){
$.getJSON("score.json",
function (data) {
var tr;
for (var i = 0; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + data[i].User_Name + "</td>");
tr.append("<td>" + data[i].score + "</td>");
tr.append("<td>" + data[i].team + "</td>");
$('table').append(tr);
}
});
});
What I need to do:
Display these table rows in descending order based on the "score" value.
Add a "rank" column with a dynamically generated number inserted with each row
I am just a beginner with JavaScript so any help would be much appreciated.
EDIT: Solved. Final code below:
$(document).ready(function(){
$.getJSON("score.json",
function (data) {
var tr;
data.sort(function(a,b) { return parseFloat(b.score) - parseFloat(a.score) } );
var rank = 1;
for (var i = 0; i < data.length; i++) {
tr = $('<tr/>');
tr.append("<td>" + rank + "</td>");
tr.append("<td>" + data[i].User_Name + "</td>");
tr.append("<td>" + data[i].score + "</td>");
tr.append("<td>" + data[i].team + "</td>");
$('table').append(tr);
rank = rank +1;
}
});
});
you can use this to sort your array :
json.sort(function(a,b) { return parseFloat(b.score) - parseFloat(a.score) } );
Here is the jsFiddle.

Categories