Yahoo finance xchange - taking the last update time - javascript

I'm doing a query on Yahoo finance xchange, but seems the time of update is not the most updated. Seems random, for each refresh, this value change, sometimes most updated, and sometimes less updated.
There is a way to always get the last time it was updated ?
Thank you.
$.getJSON("https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.xchange%20where%20pair%20in%20(%22USDUSD%22%2C%22USDEUR%22%2C%20%22USDJPY%22%2C%20%22USDCNY%22%2C%20%22USDGBP%22%2C%20%22USDBRL%22%2C%20%22EUREUR%22%20%2C%22EURUSD%22%2C%20%22EURJPY%22%2C%20%22EURCNY%22%2C%20%22EURGBP%22%2C%20%22EURBRL%22)&format=json&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=", function (data) {
var indices = '<p style=\"border:1px solid #ccc; width:auto; padding:0 10px; background:#ddd;\"><strong>' + data.query.results.rate[0].Name + '</strong> ' + money(data.query.results.rate[0].Rate) + '</p>' +
'<p><strong>' + data.query.results.rate[1].Name + '</strong> (Fechamento ' + money(data.query.results.rate[1].Rate) + ') - ' + data.query.results.rate[1].Date + ' - ' + data.query.results.rate[1].Time + '</p>' +
'<p><strong>' + data.query.results.rate[2].Name + '</strong> (Fechamento ' + money(data.query.results.rate[2].Rate) + ') - ' + data.query.results.rate[2].Date + ' - ' + data.query.results.rate[2].Time + '</p>' +
'<p><strong>' + data.query.results.rate[3].Name + '</strong> (Fechamento ' + money(data.query.results.rate[3].Rate) + ') - ' + data.query.results.rate[3].Date + ' - ' + data.query.results.rate[3].Time + '</p>' +
'<p><strong>' + data.query.results.rate[4].Name + '</strong> (Fechamento ' + money(data.query.results.rate[4].Rate) + ') - ' + data.query.results.rate[4].Date + ' - ' + data.query.results.rate[4].Time + '</p>' +
'<p><strong>' + data.query.results.rate[5].Name + '</strong> (Fechamento ' + money(data.query.results.rate[5].Rate) + ') - ' + data.query.results.rate[5].Date + ' - ' + data.query.results.rate[5].Time + '</p>' +
'<p style=\"border:1px solid #ccc; width:auto; margin:20px 0 0; padding:0 10px; background:#ddd;\"><strong>' + data.query.results.rate[6].Name + '</strong> ' + money(data.query.results.rate[6].Rate) + '</p>' +
'<p><strong>' + data.query.results.rate[8].Name + '</strong> (Fechamento ' + money(data.query.results.rate[8].Rate) + ') - ' + data.query.results.rate[8].Date + ' - ' + data.query.results.rate[8].Time + '</p>' +
'<p><strong>' + data.query.results.rate[7].Name + '</strong> (Fechamento ' + money(data.query.results.rate[7].Rate) + ') - ' + data.query.results.rate[7].Date + ' - ' + data.query.results.rate[7].Time + '</p>' +
'<p><strong>' + data.query.results.rate[9].Name + '</strong> (Fechamento ' + money(data.query.results.rate[9].Rate) + ') - ' + data.query.results.rate[9].Date + ' - ' + data.query.results.rate[9].Time + '</p>' +
'<p><strong>' + data.query.results.rate[10].Name + '</strong> (Fechamento ' + money(data.query.results.rate[10].Rate) + ') - ' + data.query.results.rate[10].Date + ' - ' + data.query.results.rate[10].Time + '</p>' +
'<p><strong>' + data.query.results.rate[11].Name + '</strong> (Fechamento ' + money(data.query.results.rate[11].Rate) + ') - ' + data.query.results.rate[11].Date + ' - ' + data.query.results.rate[11].Time + '</p>';
$('#info').html(indices);
});
money = function (n) {
var
c = 4,
d = ',',
t = '.',
s = n < 0 ? "-" : "",
i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
j = (j = i.length) > 3 ? j % 3 : 0;
return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
};

Well, I ended up constructing a date for each element in the array (map) and then filtering them to the oldest date (reduce)
what do you want to do with this date, I am not sure but here it is...
UPDATED
updated to return full JSON record containing the latest date/time stamp (instead of returning only the latest date)
// sample response
var response = {"query":{"count":12,"created":"2016-04-29T20:13:39Z","lang":"en-us","results":{"rate":[{"id":"USDUSD","Name":"USD/USD","Rate":"1.0000","Date":"N/A","Time":"N/A","Ask":"1.0000","Bid":"1.0000"},
{"id":"USDEUR","Name":"USD/EUR","Rate":"0.8775","Date":"4/29/2016", "Time":"12:38pm","Ask":"0.8777","Bid":"0.8775"},{"id":"USDJPY","Name":"USD/JPY","Rate":"107.3910","Date":"4/29/2016","Time": "2:55pm","Ask":"107.3940","Bid":"107.3910"},{"id":"USDCNY","Name":"USD/CNY","Rate":"6.4868","Date":"4/29/2016","Time":"12:49pm","Ask":"6.4878","Bid":"6.4868"},{"id":"USDGBP","Name":"USD/GBP","Rate":"0.6843","Date":"4/29/2016","Time":"1:15pm","Ask":"0.6844","Bid":"0.6843"},{"id":"USDBRL","Name":"USD/BRL","Rate":"3.4492","Date":"4/29/2016","Time":"3:33pm","Ask":"3.4496","Bid":"3.4492"},{"id":"EUREUR","Name":"EUR/EUR","Rate":"1.0000","Date":"1/29/2016","Time":"8:26am","Ask":"1.0002","Bid":"0.9998"},{"id":"EURUSD","Name":"EUR/USD","Rate":"1.1443","Date":"4/29/2016","Time":"3:08pm","Ask":"1.1443","Bid":"1.1443"},{"id":"EURJPY","Name":"EUR/JPY","Rate":"122.5650","Date":"4/29/2016","Time":"4:00pm","Ask":"122.6200","Bid":"122.5100"},{"id":"EURCNY","Name":"EUR/CNY","Rate":"7.4054","Date":"4/29/2016","Time":"2:08pm","Ask":"7.4070","Bid":"7.4037"},{"id":"EURGBP","Name":"EUR/GBP","Rate":"0.7836","Date":"4/29/2016","Time":"3:22pm","Ask":"0.7837","Bid":"0.7836"},{"id":"EURBRL","Name":"EUR/BRL","Rate":"3.9637","Date":"4/29/2016","Time":"4:28pm","Ask":"3.9679","Bid":"3.9595"}]}}};
//console.log(response.query.results.rate);
var times = response.query.results.rate.map(function(elem){
if( elem.Time === 'N/A' || elem.Time === 0){
elem.fullDateTimeStamp = elem.Time;
//console.log(elem);
return elem;
}
// create full date from the time (using time and date combined)
// 1) is it AM or PM
var elemIsPm = (elem.Time.substring(elem.Time.length-2).indexOf("am") == -1);
// 2) remove AM/PM and get hour:min into array
var elemArr = elem.Time.substring(0, elem.Time.length-2).split(":");
// 3) add 12 hours if PM and not noon
if( elemIsPm && elemArr[0] != 12){
elemArr[0] = parseInt(elemArr[0]) + 12;
}
//console.log(elemArr[0]);
// 4) however, if it is 12, we deduct 12 if it's not PM
if( elemArr[0] == 12 && !elemIsPm ){
elemArr[0] = elemArr[0] - 12;
}
// 5) create date object
var elemDateString = elem.Date;
var elemDateOnly = new Date(elemDateString);
//console.log(elemDateOnly);
var elemTS = new Date(elemDateOnly.getFullYear(), elemDateOnly.getMonth(), elemDateOnly.getDate(), elemArr[0], elemArr[1], 0, 0);
elem.fullDateTimeStamp = elemTS;
// console.log(elem);
// 4) return
return elem;
});
console.log( times );
var lastOne = times.reduce(function(prevVal, elem) {
// console.log('p');
// console.log(prevVal );
// console.log('e');
// console.log(elem );
if( prevVal === 'N/A' || prevVal === 0 || prevVal.Time){
return elem;
}
//console.log(prevVal.fullDateTimeStamp);
return (prevVal.fullDateTimeStamp < elem.fullDateTimeStamp)? elem : prevVal;
}, 0);
document.getElementById('latest').innerHTML = JSON.stringify(lastOne);
console.log('====> ');
console.log( JSON.stringify(lastOne.fullDateTimeStamp) );
Last date:
<div id='latest'></div>

Related

Cannot read item in nested array?

I have a nested array inside a list like the following:
{total_results, page, results [id, species_guess, observed_on_details {date, week, month, hour, year}]}
I am trying to get just the id, species_guess, and date using forEach.
function observationSummary2(data) {
data.results.forEach(element =>
console.log('#' + data.results.id +
" - " + data.results.species_guess +
' (' + data.results.observed_on_details.date + ')')
);
}
This is saying " Cannot read property 'date' of undefined ". I have tried using a for loop like this and it worked just fine.
for (let i = 0; i < data.results.length; i++) {
console.log('#' + data.results[i].id + " - " + data.results[i].species_guess + ' (' + data.results[i].observed_on_details.date + ')');
}
Can anyone tell me where am I doing wrong here, sorry I am still new at this language.
you should use foreach as follow
function observationSummary2(data) {
data.results.forEach(element =>
console.log('#' + element.id +
" - " + element.species_guess +
' (' + element.observed_on_details.date + ')')
);
}
Instead of
function observationSummary2(data) {
data.results.forEach(element =>
console.log('#' + data.results.id +
" - " + data.results.species_guess +
' (' + data.results.observed_on_details.date + ')')
);
}
Replace "data.results" with "element"
function observationSummary2(data) {
data.results.forEach(element =>
console.log('#' + element.id +
" - " + element.species_guess +
' (' + element.observed_on_details.date + ')')
);
}
More info about "forEach()" here:
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

Merge every two elements into 1 element in javascript array

Suppose I have the following array in JavaScript:
var dataArray= [
'name1\n' +
'\n' +
'name2\n' +
'name3',
' \n' +
'name4\n' +
'name5\n' +
'\n' +
'name6\n' +
'name7\n' +
'\n' +
'name8',
'name9\n' +
'\n' +
'name10\n' +
'name11',
' \n' +
'name12\n' +
'name13\n' +
'\n' +
'name14\n' +
'name15',
'name16\n' +
'\n' +
'name17\n' +
'name18',
' \n' +
'name19\n' +
'name20\n' +
'\n' +
'name21\n' +
'name22\n' +
'\n' +
'name23',
'name24\n' +
'\n' +
'name25\n' +
'name26',
' \n' +
'name27\n' +
'name28\n' +
'\n' +
'name29\n' +
'name30',
]
How can I write code to merge every two elements into one element? So that each pair, is only separated by 1 comma?
I'm looking to get the following output:
var dataArray= [
'name1\n' +
'\n' +
'name2\n' +
'name3'
' \n' +
'name4\n' +
'name5\n' +
'\n' +
'name6\n' +
'name7\n' +
'\n' +
'name8',
'name9\n' +
'\n' +
'name10\n' +
'name11'
' \n' +
'name12\n' +
'name13\n' +
'\n' +
'name14\n' +
'name15',
'name16\n' +
'\n' +
'name17\n' +
'name18'
' \n' +
'name19\n' +
'name20\n' +
'\n' +
'name21\n' +
'name22\n' +
'\n' +
'name23',
'name24\n' +
'\n' +
'name25\n' +
'name26',
' \n' +
'name27\n' +
'name28\n' +
'\n' +
'name29\n' +
'name30',
]
I want it to be like the above, whereby every 2 elements are amalgamated.
You can use Array.from, assuming that the length of the array is even.
const res = Array.from({length:dataArray.length/2}, (_,i)=>dataArray[2*i]+dataArray[2*i+1]);
var dataArray= [
'name1\n' +
'\n' +
'name2\n' +
'name3',
' \n' +
'name4\n' +
'name5\n' +
'\n' +
'name6\n' +
'name7\n' +
'\n' +
'name8',
'name9\n' +
'\n' +
'name10\n' +
'name11',
' \n' +
'name12\n' +
'name13\n' +
'\n' +
'name14\n' +
'name15',
'name16\n' +
'\n' +
'name17\n' +
'name18',
' \n' +
'name19\n' +
'name20\n' +
'\n' +
'name21\n' +
'name22\n' +
'\n' +
'name23',
'name24\n' +
'\n' +
'name25\n' +
'name26',
' \n' +
'name27\n' +
'name28\n' +
'\n' +
'name29\n' +
'name30',
];
const res = Array.from({length:dataArray.length/2}, (_,i)=>dataArray[2*i]+dataArray[2*i+1]);
console.log(res);

How can I filter null or undefined values from an ajax call?

I'm trying to create a simple class directory for my kid's class. I have a Array of students in JSON format and wrote an AJAX call for the kids' names, and parents information. But some don't have two parents or two sets of contact information? I have tried "if (studentData !== null) {
show the data} but that doesn't work.
function showStudents() {
var currentURL = window.location.origin;
$.ajax({ url: currentURL + '/api/students', method: 'GET'})
.then(function(studentData) {
console.log("------------------------------------");
console.log("URL: " + currentURL + "/api/students");
console.log("------------------------------------");
// Here we then log the NYTData to console, where it will show up as an object.
console.log(studentData);
console.log("------------------------------------");
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
studentSection.addClass('card');
studentSection.attr('id', 'studentCard-' + i);
studentSection.attr('style', 'width:25rem');
$('#studentSection').append(studentSection);
$('#studentCard-' + i ).append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>');
$('#studentCard-' + i ).append('<ul class="list-group list-group-flush>');
$('#studentCard-' + i ).append('<li class="list-group-item"><h5>Parent(s):</h5>' + studentData[i].parent1 + ' & ' + studentData[i].parent2 +' </li>');
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
$('#studentCard-' + i ).append('</ul>');
$('#studentCard-' + i ).append('</div>');
}
});
}
It sounds like it's the parent1 or parent2 properties that might not exist, and the contact1 or contact2 properties that might not exist. It doesn't make sense to test if the entire response is null - just check those properties instead. For example:
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
studentSection.addClass('card');
studentSection.attr('id', 'studentCard-' + i);
studentSection.attr('style', 'width:25rem');
$('#studentSection').append(studentSection);
$('#studentCard-' + i ).append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>');
$('#studentCard-' + i ).append('<ul class="list-group list-group-flush>');
// Start of changes
const parentStr = [studentData[i].parent1, studentData[i].parent2].filter(Boolean).join(' & ');
$('#studentCard-' + i ).append('<li class="list-group-item"><h5>Parent(s):</h5>' + parentStr +' </li>');
if (studentData[i].contact1) {
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
}
if (studentData[i].contact2) {
$('#studentCard-' + i ).append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
}
// End of changes
$('#studentCard-' + i ).append('</ul>');
$('#studentCard-' + i ).append('</div>');
}
Your script structure could be improved too - unless each card's id is particularly important, it would make more sense to use a class instead of unique ids for every single element, or perhaps to leave it off entirely if you're only using it to select the newly created container. You already have a reference to the element you just created with studentSection, so just reference that variable again. You can also use method chaining to reduce your syntax noise:
CSS:
.card {
width: 25rem;
}
(that will keep you from having to manually set the width of each created element in your JS)
JS loop:
for (var i = 0; i < studentData.length; i++ ) {
var studentSection = $('<div>');
$('#studentSection').append(studentSection);
const parentStr = [studentData[i].parent1, studentData[i].parent2].filter(Boolean).join(' & ');
studentSection.addClass('card')
.append('<div class="card-header"><h3>' + studentData[i].firstName + ' ' + studentData[i].lastName + '</h3></div>')
.append('<ul class="list-group list-group-flush>')
.append('<li class="list-group-item"><h5>Parent(s):</h5>' + parentStr +' </li>');
if (studentData[i].contact1) {
studentSection.append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact1 + '<br> email: ' + studentData[i].email1 + '</li>');
}
if (studentData[i].contact2) {
studentSection.append('<li class="list-group-item">' + 'phone: ' + studentData[i].contact2 + '<br> email: ' + studentData[i].email2 + '</li>');
}
studentSection.append('</ul>');
.append('</div>');
}
(Or, even better, use template literals instead)

JS dropdown 14 days in future [duplicate]

This question already has answers here:
How to get next seven days from X and format in JS
(6 answers)
next 7 days in drop-down list [duplicate]
(3 answers)
Closed 5 years ago.
I am trying to create a dropdown list that shows 14 days in the future via JS.
Right now it is showing only 7 days but with duplicates.
What is wrong?
screenshot dropdown
function createDates() {
$("#DT").find('option').remove().end().append('<option value="" selected>~#SELECT_DT~</option>');
var counter = 0;
var index = 1;
console.log(holidays);
while (counter < 14) {
var date = new Date();
date.setDate(date.getDate() + index);
var day = date.getDay();
var month = date.getMonth() + 1;
var isWeekend = (day == 6) || (day == 0);
var checkTime1 = getTimeOfDate(date.getFullYear(), month, date.getDate());
var isFound = false;
var selected = "";
if (index == ~(IF(#DT<>'',#DT,0))~) {
selected = 'selected="selected"';
}
if (!isWeekend) {
if (holidays.length > 0) {
$.each(holidays, function(key, obj) {
var hDay = new Date(obj.DT);
var checkTime2 = getTimeOfDate(hDay.getFullYear(), hDay.getMonth() + 1, hDay.getDate());
if (checkTime1 == checkTime2) {
isFound = true;
}
});
} else {
$("#DT").append('<option value="' + index + '"' + selected + '>' + getDayString(day) + ' ' + date.getDate() + ' ' + getMonthString(month) + ' ' + date.getFullYear() + '</option>');
counter++;
}
if (!isFound) {
$("#DT").append('<option value="' + index + '"' + selected + '>' + getDayString(day) + ' ' + date.getDate() + ' ' + getMonthString(month) + ' ' + date.getFullYear() + '</option>');
counter++;
}
}
index++;
}
}
The second if block should come under the first, also set isFound to false in the beginning:
if (!isWeekend) {
isFound = false;
if (holidays.length > 0) {
$.each(holidays, function(key, obj) {
var hDay = new Date(obj.DT);
var checkTime2 = getTimeOfDate(hDay.getFullYear(), hDay.getMonth() + 1, hDay.getDate());
if (checkTime1 == checkTime2) {
isFound = true;
}
});
if (!isFound) {
$("#DT").append('<option value="' + index + '"' + selected + '>' + getDayString(day) + ' ' + date.getDate() + ' ' + getMonthString(month) + ' ' + date.getFullYear() + '</option>');
counter++;
}
} else {
$("#DT").append('<option value="' + index + '"' + selected + '>' + getDayString(day) + ' ' + date.getDate() + ' ' + getMonthString(month) + ' ' + date.getFullYear() + '</option>');
counter++;
}
}

How do I replace a string in a parent page from a JS created childpage?

I am creating a dynamic list with JS
var obj = JSON.parse(Agent212);
var i;
var serie = "Agent212";
for (i = 0; i < obj.strips.length; i++) {
if (obj.strips[i].Collectie == "0") {
document.write("<li><a onclick='newPage(" + obj.strips[i].Nummer + "," + serie + ")' style = 'color:orange'>" + obj.strips[i].Nummer + " - " + obj.strips[i].Titel + "</a></li>");
}
else if (obj.strips[i].Collectie == "2") {
document.write("<li><a onclick='newPage(" + obj.strips[i].Nummer + "," + serie + ")' style = 'color:red'>" + obj.strips[i].Nummer + " - " + obj.strips[i].Titel + "</a></li>");
}
else {
document.write("<li><a class='ToHide' onclick='newPage(" + obj.strips[i].Nummer + "," + serie + ")'><strike>" + obj.strips[i].Nummer + " - " + obj.strips[i].Titel + "</strike></a></li>");
}
}
when I click on an item in the list, I create a childpage
function newPage(StripNum, SerieNaam) {
var obj = JSON.parse(SerieNaam);
var i;
var x = StripNum;
for (i = 0; i < obj.strips.length; i++) {
if (obj.strips[i].Nummer == x) {
if (obj.strips[i].Collectie == 0) {
var myWindow = window.open();
myWindow.document.writeln('<html>');
myWindow.document.writeln('<head>');
myWindow.document.writeln('<meta name="viewport" content="width=device-width, initial-scale=1">');
myWindow.document.writeln('<link rel="stylesheet" href="./css/W3CSS.css">');
myWindow.document.writeln('<scr' + 'ipt>');
myWindow.document.writeln('function windowClose(){');
myWindow.document.writeln('window.close();}'); **
myWindow.document.writeln('function ToevoegenVerzameling(){'); **
myWindow.document.writeln('window.alert("toegevoegd aan verzameling");');
myWindow.document.writeln('window.close();');
myWindow.document.writeln('}');
myWindow.document.writeln('</scr' + 'ipt>');
myWindow.document.writeln('</head>');
myWindow.document.writeln('<body>');
myWindow.document.writeln('<div class="w3-container w3-display-topmiddle">');
myWindow.document.writeln('<div class="w3-card-16 w3-round-xlarge" style="width:100%">');
myWindow.document.writeln('<a onclick="windowClose();"><center><img src="' + obj.strips[i].Link + obj.strips[i].Nummer + '.jpg"></center></a>');
myWindow.document.writeln('<div class="w3-container w3-margin-top">');
myWindow.document.writeln('<center><B>Nummer: </B><I>' + obj.strips[i].Nummer + '</I></center>');
myWindow.document.writeln('<center><B>Titel: </B><I>' + obj.strips[i].Titel + '</I></center>');
myWindow.document.writeln('<center><button onclick="ToevoegenVerzameling()" class="w3-btn w3-light-grey w3-border w3-border-black w3-round-xlarge w3-margin-top w3-margin-bottom" style="width:100%"><h2><b>Toevoegen</b></h2></button></center>');
myWindow.document.writeln('</div>');
myWindow.document.writeln('</div>');
myWindow.document.writeln('</div>');
myWindow.document.writeln('</body>');
myWindow.document.writeln('</html>');
}
all of the above does work, but know I want to ad a replace function to ToevoegenVerzameling().
I've tried with adding this piece of code.
myWindow.document.writeln('if (window.opener != null && !window.opener.closed){');
myWindow.document.writeln('var str = "<li><a onclick='
newPage(" + obj.strips[i].Nummer + ", " + serie + ")
' style = '
color: orange '>" + obj.strips[i].Nummer + " - " + obj.strips[i].Titel +"</a></li>";');
myWindow.document.writeln('str.replace("<a onclick='
newPage(", " < a class = 'ToHide'
onclick = 'newPage(");'); myWindow.document.writeln('str.replace("style = '
color: orange '>", "><\strike>");'); myWindow.document.writeln('str.replace("</a>", "</strike></a>");}');
But I can't get it to work, Were am I making a mistake in this?

Categories

Resources