JSON data from Url showing [Object Object] in Html Webspage - javascript

I have a Json Url which consists of data and in that data I want to print "title , date and notes separately but it is only showing [object object]...
I want to print data that is present inside the "events" list that have 'title' , 'date' and 'notes'
The link to Json file :- https://www.gov.uk/bank-holidays.json
I tried using events/title but it also does not work , I am new in javascript and I think I am doing a basic mistake :(
Thanks in advance
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GFG User Details</title>
<!-- INCLUDING JQUERY-->
<script src=
"https://code.jquery.com/jquery-3.5.1.js">
</script>
<!-- CSS FOR STYLING THE PAGE -->
<style>
table {
margin: 0 auto;
font-size: large;
border: 1px solid black;
}
h1 {
text-align: center;
color: #006600;
font-size: xx-large;
font-family: 'Gill Sans',
'Gill Sans MT', ' Calibri',
'Trebuchet MS', 'sans-serif';
}
td {
background-color: #E4F5D4;
border: 1px solid black;
}
th,
td {
font-weight: bold;
border: 1px solid black;
padding: 10px;
text-align: center;
}
td {
font-weight: lighter;
}
</style>
</head>
<body>
<section>
<h1>Display Table</h1>
<!-- TABLE CONSTRUCTION-->
<table id='table'>
<!-- HEADING FORMATION -->
<tr>
<th>notes</th>
<th>title</th>
<th>date</th>
<th>Division</th>
</tr>
<script>
$(document).ready(function () {
// FETCHING DATA FROM JSON FILE
$.getJSON("https://www.gov.uk/bank-holidays.json",
function (data) {
var student = '';
// ITERATING THROUGH OBJECTS
$.each(data, function (key, value) {
//CONSTRUCTION OF ROWS HAVING
// DATA FROM JSON OBJECT
student += '<tr>';
student += '<td>' +
value.events + '</td>';
student += '<td>' +
value.date + '</td>';
student += '<td>' +
value.notes + '</td>';
student += '<td>' +
value.division + '</td>'
student += '</tr>';
});
//INSERTING ROWS INTO TABLE
$('#table').append(student);
});
});
</script>
</section>
</body>
</html>

So this solves your problem #maddy.
the issue was the what you were accessing. you had to access the events array inside of the object. so here is a sample
<html lang="en">
<head>
<meta charset="UTF-8">
<title>GFG User Details</title>
<!-- INCLUDING JQUERY-->
<script src=
"https://code.jquery.com/jquery-3.5.1.js">
</script>
<!-- CSS FOR STYLING THE PAGE -->
<style>
table {
margin: 0 auto;
font-size: large;
border: 1px solid black;
}
h1 {
text-align: center;
color: #006600;
font-size: xx-large;
font-family: 'Gill Sans',
'Gill Sans MT', ' Calibri',
'Trebuchet MS', 'sans-serif';
}
td {
background-color: #E4F5D4;
border: 1px solid black;
}
th,
td {
font-weight: bold;
border: 1px solid black;
padding: 10px;
text-align: center;
}
td {
font-weight: lighter;
}
</style>
</head>
<body>
<section>
<h1>Display Table</h1>
<!-- TABLE CONSTRUCTION-->
<table id='table'>
<!-- HEADING FORMATION -->
<tr>
<th>notes</th>
<th>title</th>
<th>date</th>
<th>Division</th>
</tr>
<script>
$(document).ready(function () {
// FETCHING DATA FROM JSON FILE
$.getJSON("https://www.gov.uk/bank-holidays.json",
function (data) {
var student = '';
// ITERATING THROUGH OBJECTS
$.each(data, function (key, value) {
//CONSTRUCTION OF ROWS HAVING
// DATA FROM JSON OBJECT
// map the events array in value to have access to the required object
$.each(value.events, function(key1, val) {
student += '<tr>';
student += '<td>' +
val.notes + '</td>';
student += '<td>' +
val.title + '</td>';
student += '<td>' +
val.date + '</td>';
student += '<td>' +
value.division + '</td>'
student += '</tr>';
});
});
//INSERTING ROWS INTO TABLE
$('#table').append(student);
});
});
</script>
</section>
</body>
</html>

[object object] is the data-type of the data you are fetching. To get the actual data, you would need to parse the json-data. (parse: unpack it)
When you fetch something over the internet (at least with http-api), you get a response, but that response can't send javascript objects, so you would use a function to stringify it (example: JSON.stringify(data)).
Javascript's built-in JSON-object has a the methods needed to do so.
To access this data when it is fetched, use JSON.parse(data)

Related

how to fetch Json Data to real Time updating Html Table?

i have a Json data file where data is updating every second. i want to show data in Html page of my website in real time without loading page. i'm beginner in javascript i'm just learning please Help me. thanks in advance.
Here is My Json data file: Here
Here is My Html table Page (Result): Here
i want to show data in real time without loading page like stock price update.
please help.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.5.1.js">
</script>
<!-- CSS FOR STYLING THE PAGE -->
<style>
table {
margin: 0 auto;
font-size: large;
border: 1px solid black;
}
h1 {
text-align: center;
color: #006600;
font-size: xx-large;
font-family: 'Gill Sans',
'Gill Sans MT', ' Calibri',
'Trebuchet MS', 'sans-serif';
}
td {
background-color: #E4F5D4;
border: 1px solid black;
}
th,
td {
font-weight: bold;
border: 1px solid black;
padding: 10px;
text-align: center;
}
td {
font-weight: lighter;
}
</style>
</head>
<body>
<section>
<h1>My Google Sheet Table</h1>
<!-- TABLE CONSTRUCTION-->
<table id='mytable'>
<!-- HEADING FORMATION -->
<tr>
<th>Date</th>
<th>Name</th>
<th>Phone Number</th>
<th>Months</th>
</tr>
<script>
$(document).ready(function () {
// FETCHING DATA FROM JSON FILE
setInterval(function () {$.getJSON("JsonDataFileLink",
function (data) {
var content = '';
// ITERATING THROUGH OBJECTS
$.each(data, function (key, value) {
//CONSTRUCTION OF ROWS HAVING
// DATA FROM JSON OBJECT
content += '<tr>';
content += '<td>' +
value.SN + '</td>';
content += '<td>' +
value.Name + '</td>';
content += '<td>' +
value.Phone + '</td>';
content += '<td>' +
value.Months + '</td>';
content += '</tr>';
});
//INSERTING ROWS INTO TABLE
$('#mytable').append(content);
});
}, 3000);
});
</script>
</section>
</body>
</html>
I added your json file url to fetchData() to download the correct file and then I added a callback to be invoked when the data fetched is ready to be processed.
Data Transform: from array of objects to table rows
The transformation is a chain of map and reduce as follows...
Map (over json array of objects):
Iterates over the objects found in the json array and for each one of them it will return a new <tr> element mapped to the corresponding json object in the array.
Reduce (over the fields expected to be found in the object):
The reduction begins from the cols array telling the name of the properties that will be found in the json objects array in the same order they are wished to be displayed.
It just iterates over them, grabs the current value that gets embedded in a new <td> that gets appended to the new <tr>
Each reduce call will just return a new <tr> object as that.
Once we have the final map:
The final result is rows that just are appended to the table tbody once the processing is over.
Attention!
I see the json returned from that url isn't always the same. The date property is changing and some items at the end are empty sometimes.
Automatic refresh
I spent so much thoughts doing the data fetch algorithm that I was ignoring yours already worked and you just needed the refresh of data every once in a while without actually reloading the page.
So here I used setTimeout that will call after a given delay (pollingDelay default at 3000ms) the fetchData and at each iteration, after the table gets refreshed, it calls again the same setTimeout and updates the last time data was updated.
const pollingDelay = 3000;
function fetchData(refreshTable) {
url = 'https://script.googleusercontent.com/macros/echo?user_content_key=zASWVI1B2eWR37WJ_8Pn0h5WCuVP_1udOD8ZY6sMSzTfAo55CT4-ovYqEXJO5ZtrHrBeT9cYNecnp-Gzuq8TCmDVQfQQO1qjm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnMs1tm11-lp-Q13okfTSX_i5IzvU5JZnhqqg8H90dlfD5jU3SrNArGaMaXSvzMBh2h5A-lJ1RFia7VipeMnCxQqExfB7Qd_-iQ&lib=MVoeqw6DJ9bzix14T3i_S_jbsQ0CRhLAj';
$.getJSON(url, function(data) { refreshTable(data) });
}
//callback to be passed at fetchData
const cb = (data)=>{
//json object properties in the order how the are wished to be displayed on table
const cols = ['SN', 'Name', 'Phone', 'Months'];
var rownum = 0;
//maps the data items to table rows
const rows = data.map( entry => {
//creates a table row using reduce over cols
const newrow = cols.reduce(
(row, col) => { return $(row).append( $('<td>').text(entry[col]) ); }, $('<tr>')
);
//adds the data attribute data-rownum on the <tr>
newrow[0].dataset.rownum = ++rownum;
//returns the new row
return newrow;
});
//empties table and appends new row
$('#mytable tbody').empty().append(rows);
//updates the time at which the table was refreshed
const now = new Date();
$('#refresh').text(`Data refreshed at: ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`);
//set a new timer before calling again the fetchData()
setTimeout(fetchData(cb), pollingDelay)
}
$(document).ready(function() {
setTimeout(fetchData(cb), pollingDelay)
});
#refresh{
border: solid;
text-align: center;
font-size: 3rem;
}
table {
margin: 0 auto;
font-size: large;
border: 1px solid black;
}
h1 {
text-align: center;
color: #006600;
font-size: xx-large;
font-family: 'Gill Sans', 'Gill Sans MT', ' Calibri', 'Trebuchet MS', 'sans-serif';
}
td {
background-color: #E4F5D4;
border: 1px solid black;
}
th,
td {
font-weight: bold;
border: 1px solid black;
padding: 10px;
text-align: center;
}
td {
font-weight: lighter;
}
tr:before{
content: attr(data-rownum);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body>
<section>
<div id="refresh"></div>
<h1>My Google Sheet Table</h1>
<table id='mytable'>
<thead>
<th>Date</th>
<th>Name</th>
<th>Phone Number</th>
<th>Months</th>
</thead>
<tbody>
<tr>
<td colspan="4">Loading... please wait</td>
</tr>
</tbody>
</table>
</section>
</body>

How to show each td data in a card in html automatically after 15 second using jquery

I am showing data in a table dynamically in a table, I grt json data and show in html table dynamically. There is a card in html with that table, so I want to show each tr data in that card after 15 second means on load the first tr data shows in card and after 15 seconds the second tr data show in that same card and first tr data remove. I want to show each tr data in that card every 15 seconds
My code
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<head></head>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<style type="text/css" media="all">
body {
text-align: center;
box-sizing: border-box;
}
.card {
box-shadow: 0 0 3px rgba(0, 0, 0, 0.5);
width: 200px;
padding: 10px;
margin: 10px;
}
.tr {
background: blue;
color: white;
transition: background .3s;
}
.table {
border-collapse: collapse;
border: 1px solid #ddd;
}
.table td {
padding: 10px 15px;
}
</style>
</head>
<body>
<div class="card">
<span id="value">25 </span><span id="unit">ppm</span>
<p id="parameter">Sodium Oxide</p>
</div>
<div class="table-responsive">
<table class="table" border="1">
<thead>
<tr>
<th scope="col">Parameter</th>
<th scope="col">Alias</th>
<th scope="col">Cordinates</th>
<th scope="col">Location</th>
</tr>
</thead>
<tbody id="scroll">
</tbody>
</table>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$.getJSON('./data.json', function(data) {
console.log(data)
var tdata = '';
$.each(data, function(key, value) {
console.log(value.deviceId)
tdata += '<tr>' + '<td>' + value.deviceId + '</td>' + '<td>' + value.aliasname + '</td>' + '<td>' + value.cordinates + '</td>' + '<td>' + value.location + '</td>' + '</tr>'
})
})
})
</script>
</body>
</html>
You need to call each DOM modification after a setTimeout. Here, I use async/await syntax:
const tbody = $('#scroll');
const sleep = (millis) => new Promise( resolve => setTimeout(resolve, millis));
$.getJSON('./data.json', async function(data) {
console.log(data);
// Forever loop over the received values
while(1) {
// For each value in data, replace table data
// with new tr containing data's value
for(const value of data) {
console.log(value.deviceId);
tbody.html(`<tr><td>${value.deviceId}</td><td>${value.aliasname}</td><td>${value.cordinates}</td><td>${value.location}</td></tr>`);
await sleep(15_000);
}
}
});

Moving Requested Objects to Separate Rows within a Table

I have a search filter that I would like to use to find channels on my page as the user is typing it. However, when calling on this API, I am unable to separate each object into a different row because the channel objects are all stored within the same row of the table data. I am storing the objects in their respective table data, but don't know a specific way of tackling this problem. Should I be using a for loop or perhaps add more table datas in my HTML? You can check out my codepen and remove the comment braces to run the last for loop within my function to get an idea.
https://codepen.io/baquino1994/pen/EvLrPV
HTML:
<head>
<link href="https://fonts.googleapis.com/css?family=Saira+Condensed" rel="stylesheet">
</head>
<body>
<div class='container-fluid'>
</div>
<div class='text-center' id="border">
<h1 id="font">Twitch TV JSON API</h1>
<h2 id="fcc" target="_blank"></h2>
</div>
<!-- <div class='spacer'></div>
<div id="border">
<div class='row'>
<div class='col-md-3' id='channel'>
Channel:<br>
</div>
<div class='col-md-3' id='status'>
Status:<br>
</div>
<div class='col-md-3' id='game'>
Game:<br>
</div>
<div class='col-md-3' id="logo">
Logo:
</div> -->
<!-- <div id='follower'>Remove me<div> -->
<!-- </div> -->
<div class="container">
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for Channel.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:25%;color:#FAF0E6">Channel</th>
<th style="width:25%;color:#FAF0E6">Status</th>
<th style="width:25%;color:#FAF0E6">Game</th>
</tr>
<tr>
<td id="channel"style="color:red"></td>
<td id="status"></td>
<td id="game"></td>
</tr>
</table>
</div>
<div class='spacer'></div>
<!-- </div> -->
</body>
CSS
body{
background-image:url('https://www.twitch.tv/p/assets/uploads/combologo_474x356.png');
}
#border {
background-color: #000000;
color: white;
padding: 50px;
width: 35%;
margin-right: auto;
margin-left: auto;
border-radius: 0px;
font-size: 1.5em;
padding-bottom: 2%;
}
a{
color:white;
}
.spacer {
padding: 1%;
}
/* * {
box-sizing: border-box;
} */
#myInput {
background-position: 10px 10px;
background-repeat: no-repeat;
width: 100%;
font-size: 16px;
padding: 12px 20px 12px 40px;
border: 1px solid red;
margin-bottom: 12px;
}
#myTable {
border-collapse: collapse;
width: 100%;
border: 1px solid #ddd;
font-size: 18px;
background-color:black;
}
#myTable th, #myTable td {
text-align: left;
padding: 12px;
color:red;
}
#myTable tr {
border-bottom: 1px solid #ddd;
}
#channel{
color:red;
}
#font, #fcc, .header, #channel, #status, #game {
font-family: 'Saira Condensed', sans-serif;
}
.intro{
color:green;
}
JS
$(function() {
var follower = ["ESL_SC2", "OgamingSC2", "cretetion", "freecodecamp", "storbeck", "habathcx", "RobotCaleb", "noobs2ninjas", "brunofin"];
//An array of users or in this case, streamers that will be placed on the document.
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/streams/freecodecamp',
headers: {
'client-ID': 'ziu3fledjh14rd812socrwluiz1o31'
},
// Twitch requires a client id to request their data now. You can bypass this by using the https://wind-bow.glitch.me/twitch-api/streams/ESL_SC2?callback=? url to request certain objects. However, some objects won't be available if you do choose to bypass registering for a client_id.
success: function(data) {
if (data.stream === null) {
$('#fcc').html(' FreeCodeCamp is Offline');
} else {
$('#fcc').html(' FreeCodeCamp is Online!');
}
},
error: function(err) {
alert("Error");
}
});
for (var i = 0; i < follower.length; i++) {
//change this to get
$.ajax({
type: 'GET',
url: 'https://api.twitch.tv/kraken/streams/' + follower[i],
headers: {
'client-ID': '59x9ex7f5zzongzntqx0zrwleoxy12'
},
//You could also use $.getJSON and use the client_Id as a token to request Twitch's objects.
success: function(dataI) {
var name = dataI._links.self.slice(37)
if (dataI.stream === null) {
$('#status').append(' is Offline<br>')
$('#channel').append('<a target="blank" href="https://www.twitch.tv/' + name + '">' + name + '</a><br>')
$('#game').append('N/A<br>');
} else {
$('#status').append(' is Online<br>')
$('#channel').append('<a target="blank" href="https://www.twitch.tv/' + name + '">' + name + '</a><br>')
$('#game').append(dataI.stream.game + '<br>');
}
},
error: function(err) {
alert("Error: One or more users is no longer avaialble");
}
});
}
// for(var i=0; i< follower.length;i++){
// $.ajax({
// type:'GET',
// url:'https://api.twitch.tv/kraken/channels/'+ follower[i],
// headers:{
// 'client-ID': '59x9ex7f5zzongzntqx0zrwleoxy12'
// },
// success: function(d2){
// var logo = d2.logo;
// if(d2.logo == null){
// $('#logo').append('<img src= http://jesusldn.com/wp-content/uploads/2015/06/noimage.png>')
// }
// else{
// $("#logo").append('<img src='+logo+">'")
// }
// }
// });
// }
})
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[0];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
I have a provided a link to my codepen, as it has the Jquery plug-in and Bootstrap.
your filter works like a charm. Issues is with table creation.
you need to update your code to add <tr> dynamically to table.
remove tr from html:
<div class="container">
<input type="text" id="myInput" onkeyup="myFunction()" placeholder="Search for Channel.." title="Type in a name">
<table id="myTable">
<tr class="header">
<th style="width:25%;color:#FAF0E6">Channel</th>
<th style="width:25%;color:#FAF0E6">Status</th>
<th style="width:25%;color:#FAF0E6">Game</th>
</tr>
</table>
</div>
<div class='spacer'></div>
change your success method to this:
success: function(dataI) {
var name = dataI._links.self.slice(37)
console.log(follower);
if (dataI.stream === null) {
$('#myTable').append('<tr>'+
'<td><a target="blank" href="https://www.twitch.tv/'+name + '">' + name +
'<td>is Offline</td>'+
'</a></td>'+
'<td>NA</td>');
} else {
$('#myTable').append('<tr>'+
'<td><a target="blank" href="https://www.twitch.tv/'+name + '">' + name +
'<td>is online</td>'+
'</a><'+
'<td>NA</td>');
}
},

Javascript Loan Calculator with While loop

The program is supposed to determine how many months it will take to pay off the loan. Cannot seem to figure out how to fix my mathematical calculations. Not sure if it's the while loop that's wrong. Instead of determining the monthly payment based on user input, the input shows the total number of months (which i do not want. the program is supposed to do that). It is supposed to look like this: http://snag.gy/9vzGi.jpg Here is the code:
<html>
<head>
<title></title>
<script type="text/javascript">
function fixVal(value,numberOfCharacters,numberOfDecimals,padCharacter) {
var i, stringObject, stringLength, numberToPad;
value = value * Math.pow(10,numberOfDecimals);
value = Math.round(value);
stringObject = new String(value);
stringLength = stringObject.length;
while(stringLength < numberOfDecimals) {
stringObject = "0"+stringObject;
stringLength=stringLength+1;
}
if(numberOfDecimals>0) {
stringObject=stringObject.substring(0,stringLength-numberOfDecimals)+"."+
stringObject.substring(stringLength-numberOfDecimals,stringLength);
}
if (stringObject.length<numberOfCharacters && numberOfCharacters>0) {
numberToPad=numberOfCharacters-stringObject.length;
for (i=0; i<numberToPad; i=i+1) {
stringObject=padCharacter+stringObject;
}
}
return stringObject;
}
function buildTable() {
var amount=parseFloat(document.getElementById("loanAmt").value );
var numpay=parseInt(document.getElementById("monthlyPay").value );
var rate=parseFloat(document.getElementById("intRte").value );
rate = rate / 100;
var monthly = rate / 12;
var payment = ((amount * monthly) / (1-Math.pow((1 + monthly), - numpay)));
var total = payment * numpay;
var interest = total - amount;
var msg = "<table border='4' width='75%'>";
msg += "<tr>";
msg += "<td>Month</td>";
msg += "<td>Principal Paid</td>";
msg += "<td>Interest Paid</td>";
msg += "<td>Loan Balance</td>";
msg += "</tr>";
newPrincipal=amount;
var i = 1;
while (i <= numpay) {
newInterest=monthly*newPrincipal;
reduction=payment-newInterest;
newPrincipal=newPrincipal-reduction;
msg += "<tr><td align='left' bgcolor='pink'>"+i+"</td> \
<td align='left' bgcolor='pink'>"+fixVal(reduction,0,2,' ')+"</td> \
<td align='left' bgcolor='pink'>"+fixVal(newInterest,0,2,' ')+"</td> \
<td align='left' bgcolor='pink'>"+fixVal(newPrincipal,0,2,' ')+"</td></tr>";
i++;
}
msg += "</table>";
document.getElementById("results").innerHTML = msg;
}
</script>
<style type="text/css">
body {
background: black;
font-family: arial;
}
#contentwrap {
width: 700px;
margin: 40px auto 0px auto;
background: #FFFFCC;
text-align: center;
border: 6px red solid;
border-radius: 10px;
padding: 40px;
}
table {
border: 5px blue double;
background-color: #FFFFCC;
}
#header {
text-align: center;
font-size: 2.5em;
text-shadow: yellow 3px 3px;
margin-bottom: 18px;
color: red;
}
#button {
background: blue;
color: white;
cursor: pointer;
padding: 5px 0px 5px 0px;
border: 1px solid red;
border-radius: 25px;
width: 150px;
}
.contentTitles {
color: green;
font-weight: bold;
}
.style {
background: lightblue;
font-family: comic sans ms;
border: 6px blue double;
color: green;
font-weight: bold;
}
</style>
</head>
<body>
<div id="contentwrap">
<div id="header">Javascript Loan Calculator</div>
<form>
<div class="contentTitles">Enter Loan Amount<br />
<input type="text" id="loanAmt" class="style"><p />
Interest Rate (%)<br />
<input type="text" id="intRte" class="style"><p />
Monthly Payment Amount<br />
<input type="text" id="monthlyPay" class="style"><p />
<div style="margin-top:20px;">
<input type="button" value="Process Data" id="button" onClick="buildTable()">
</div>
</form>
<center>
<div id="results" style="margin-top:20px;"></div>
</center>
</div> <!-- ends div#contentwrap -->
</body>
</html>
If you want the input to be the monthly payment, please don't call the respective variable numpay.
In your case, it seems more practical not to calculate the number of months beforehand. You can use the while loop to build the table and calculate the duration of the loan at the same time:
function buildTable() {
var amount = parseFloat(document.getElementById("loanAmt").value );
var monthly = parseInt(document.getElementById("monthlyPay").value );
var rate = parseFloat(document.getElementById("intRte").value );
rate = rate / 100 / 12;
var m = 0; // number of months
while (amount > 0) {
var interest = amount * rate;
var principal = monthly - interest;
if (principal > amount) {
principal = amount;
amount = 0.0;
} else {
amount -= principal;
}
// build table: m + 1, principal, interest, amount
m++;
}
// display table
}

Cannot call method 'getElementsByTagName' of null

This is my first AJAX and my first use of .php file. I'm following an exercise in the text and it's not working. I tried to use the alert function as many times as possible to check what is feeding in to variables and functions, but I'm really unsure what's going on in the background. I checked the Yahoo! Weather RSS feed which is supposed to give this website some information ("http://weather.yahooapis.com/forecastrss?p=94558") and I do see the "item" tag. The console keeps saying "Cannot call method 'getElementsByTagName"!! Appreciate any input in advance....
<!DOCTYPE html PUBLIC "-\\W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title>Weather Report</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<style type="text/css">
html {
height: 100%;
margin: 0;
padding: 0;
}
body
{
height: 100%;
margin: 0;
padding: 0;
}
a { color: #91c056; }
a:link { color: #515151; text-decoration: none; }
a:visited { color: #515151; text-decoration: none; }
a.back:hover { color: #6eece3; }
#content-pane{
font-family: Courier New, monospace;
letter-spacing: -0.05em;
font-size: 15px;
line-height: 23px;
float:left;
width:100%;
padding-left: 5%;
padding-top: 5%;
}
#headline
{
font-family: Helvetica, "Helvetica Neue", Arial, sans-serif;
font-weight: bold;
letter-spacing: -0.05em;
font-size: 60px;
line-height: 60px;
color: #323232;
text-align: left;
}
</style>
<script type="text/javascript">
/* <![CDATA[ */
var weatherRequest = false;
function getRequestObject(){
try {
httpRequest = new XMLHttpRequest();
}
catch (requestError){
try {
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (requestError) {
try{
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch (requestError){
window.alert("Your browser does not support AJAX!");
return false;
}
}
}
return httpRequest;
}
function weatherUpdate(){
if(!weatherRequest)
weatherRequest = getRequestObject();
var zip = document.forms[0].zip.value;
weatherRequest.abort();
weatherRequest.open("get", "WeatherReport.php?zip=" + zip, true);
weatherRequest.send(null);
weatherRequest.onreadystatechange=fillWeatherInfo;
}
function fillWeatherInfo(){
if (weatherRequest.readyState == 4 && weatherRequest.status == 200){
var weather = weatherRequest.responseXML;
var weatherItems=weather.getElementsByTagName("item");
if (weatherItems.length > 0){
for (var i=0; i<weatherItems.length; ++i){
var curHeadline = weatherItems[i].getElementsByTagName("title")[0].childNodes[0].nodeValue;
var curLink = weatherItems[i].getElementsByTagName("link")[0].childNodes[0].nodeValue;
var curPubDate = weatherItems[i].getElementsByTagName("pubDate")[0].childNodes[0].nodeValue;
var curDesc = weatherItems[i].getElementsByTagName("description")[0].childNodes[0].nodeValue;
var weatherSpot = document.getElementById('weatherPara');
var curStory = "<a href='" + curLink + "'>" + curHeadline + "</a><br />";
curStory += "<span style='color: gray'>";
curStory += curDesc + "<br />";
weatherSpot.innerHTML = curStory;
}
}
else
window.alert("Invalid ZIP code.");
}
}
/* }]> */
</script>
</head>
<body onload ="weatherUpdate()">
<div id="content-pane">
go back
<div id="headline">Weather Report</div>
<br />
<br />
<br />
<br />
<form method="get" action="">
<p>ZIP code <input type="text" name="zip" value="94558"/> <input type="button" value="Check Weather" onclick="weatherUpdate()" /></p>
</form>
<p id="weatherPara"></p>
</div>
</body>
</html>
Below is the WeatherReport.php file.
<?php
$Zip = $_GET["zip"];
$WeatherURL
= "http://weather.yahooapis.com/forecastrss?p=" . $Zip;
header("Content-Type: text/xml");
header("Content-Length: " . strlen(file_get_contents($WeatherURL)));
header("Cache-Control: no-cache");
readfile($WeatherURL);
?>
Try adding your WeatherReport.php in form action. You have to specify your php file in you action otherwise the form will point to the same file.
In your function fillWeatherInfo, you haven't passed it any parameters. Therefore, I believe weatherRequest.responseXML is an empty object.
In your onreadystatechange property, you need to pass in the parameters of the AJAX response to the handler.

Categories

Resources