My table rows shows the same data on each row - data feched from xml files - arrays

I'm new at Javascript and i'm trying to pull data from multiple XML files.
Right now i have maneged to create 5 rows of data, but all rows contains data from the same file.
I have been trying to store the data in another array than the original one, but nothing i have tried seems too work.
My HTML code is here:
<body>
<button type="button" onclick="loadXMLDoc()" >Get my PTO DATA</button>
<br><br>
<table id="demo">
<tbody>
</tbody>
</table>
</body>
And Javascript here:
var arr = ["018338464.xml", "018340087.xml", "018340096.xml", "018340106.xml", "018340153.xml"],
cnt = 0, xmlhttp = new XMLHttpRequest(), method = "GET";
function loadXMLDoc() {
xmlhttp.open(method, arr[cnt], true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === XMLHttpRequest.DONE && xmlhttp.status == 200) {
buildTable();
}
};
xmlhttp.send();
}
function buildTable(file, xmlDoc) {
var i;
var a = 1
var xmlDoc = xmlhttp.responseXML;
var table = "<tr><th>DisplayNumber</th><th>Client</th><th>IpgClientId</th><th>Location</th><th>PracticeArea</th><th>Type</th><th>Application number</th><th>Application date</th><th>Classes</th><th>Class description</th><th>Status</th></tr>";
var x = xmlDoc.getElementsByTagName("Transaction");
for (var d = 0; d < arr.length; d++) {
console.log(`${d}: ${arr[d]}`);
var store = new Array();
for (i = 0; i < x.length; i++) {
table += "<tr><td>" +
x[i].getElementsByTagName("TransactionIdentifier")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("MarkVerbalElementText")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("Identifier")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("RegistrationOfficeCode")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("TransactionCode")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("MarkFeature")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("ApplicationNumber")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("ApplicationDate")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("ClassNumber")[0].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("GoodsServicesDescription")[2].childNodes[0].nodeValue +
"</td><td>" +
x[i].getElementsByTagName("MarkCurrentStatusCode")[0].childNodes[0].nodeValue +
"</td></tr>";
}
store[d] = a;
a++;
}
document.getElementById("demo").innerHTML = table;
}
All feedback are welcome, i'm also open to redo it all if someone has a better solution to my problem

You always load arr[cnt], and cnt is always zero. If you want loadXMLDoc to load the entire set, then you want
function loadXMLDoc() {
arr.forEach( function(name) {
xmlhttp.open(method, name, true);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState === XMLHttpRequest.DONE && xmlhttp.status == 200) {
buildTable();
}
};
xmlhttp.send();
});
}

Related

Run loop array in order

I am trying to run satellite image animation with buttons controls .l have array of dates satellite image animation.
["20200922", "20200923", "20200924", "20200925", "20200926", "20200927", "20200928"]
My code below is working fine . But when i run the code i have random output array , is not running as orderly
Code :
saturation: number = 1000
timeStops: any[];
imgs:any[]
_index :number = 0;
index: number = 0;
date$: Observable<any>;
image$: Observable<any>;
datepush: any[][];
datearray:any[]
play() {
const now = moment()
this.timeStops = [];
this.datearray = [];
for (let i = 0; i < 11; i++) {
now.subtract(15, 'minutes')
this.timeStops.push(this.roundTimeQuarterHour(now).utc().format('YYYYMMDD'));
this.imgs= [
new Image().src = "" + this.timeStops[10] + "T000000/time/00/image",
new Image().src = "" + this.timeStops[9] + "T000000/time/24/image",
new Image().src = "" + this.timeStops[8] + "T000000/time/48/image",
new Image().src = "" + this.timeStops[7] + "T000000/time/72/image",
new Image().src = "" + this.timeStops[6] + "T000000/time/96/image",
new Image().src = "" + this.timeStops[5] + "T000000/time/120/image",
new Image().src = "" + this.timeStops[4] + "T000000/time/144/image",
new Image().src = "" + this.timeStops[3] + "T000000/time/168/image",
new Image().src = "" + this.timeStops[2] + "T000000/time/192/image",
new Image().src = "" + this.timeStops[1] + "T000000/time/216/image",
new Image().src = "" + this.timeStops[0] + "T000000/time/240/image",
];
}
this.imgs.sort()
this.datearray.sort()
console.log(this.imgs)
var fortnightStart = moment();
for (let i = 1; i <= 7; i++) {
// 1, not i
this.datearray.push(fortnightStart.add(1, "days").format("YYYYMMDD"));
}
console.log(this.datearray);
console.log(this.index)
if (Math.abs(this._index) < this.imgs.length &&Math.abs(this._index) < this.datearray.length) {
this._index = this.imgs.length;
this._index = this.datearray.length;
}
this.image$ = interval(this.saturation).pipe(
map(() => {
return this.imgs[this.calculateIndex()];
}),
startWith(this.imgs[10])
);
this.date$ = interval(this.saturation).pipe(
map(() => {
return this.datearray[this.calculateIndex()];
}),
startWith(this.datearray[0])
);
}
calculateIndex(): number {
if (Math.abs(this._index) >= this.imgs.length * 3 &&Math.abs(this._index) >= this.datearray.length * 3) {
this._index = this._index % this.imgs.length;
this._index = this._index % this.datearray.length;
}
if (this.stoploop) {
this.index = this._index % this.imgs.length
this.index = this._index % this.datearray.length
return this.index;
} else {
if (this.isBackward) {
this.index = Math.abs(--this._index % this.imgs.length);
this.index = Math.abs(--this._index % this.datearray.length);
return this.index;
} else {
this.index = (++this._index % this.imgs.length);
this.index = (++this._index % this.datearray.length);
return this.index;
}
}
}
the output :
There is any way i can make the output loop as orderly ?
Live code
Your script randomizing the index, checkout I've modified your code.
startAnimation(){
this.timeOutSubsription = setInterval(()=>{
console.log(this.index)
if(this.isBackward){
this.index--;
if(this.index<0){
this.index = this._index;
}
} else{
this.index++;
if(this.index>this._index){
this.index = 0;
}
}
this.image$.next(this.imgs[this.index])
this.date$.next(this.datearray[this.index])
}, this.saturation);
}
Hope this solves your issue.

How to map and send emails to specific users who don't meet a certain criteria in Javascript/GAS

I am new in Javascript and bit by bit I have used resources here on StackOverflow to build on a project that uses external API to get time entries for users from the 10k ft project management system. I have finally have different functions together as follows:
Calls for user details which includes user_id
Get the time entries and sums up for every user who's approval has a value (pending or approval) in a specific date range. Those without approval will be ignored in the summation and their total entries left at 0.
My challenge now is to have only those with 0 as total hours of time entries receive emails to update their time entries. This code doesn't seem to select only those with 0 and send emails specifically to them. I will appreciate any pointers and/or assistance. after sending the email, this should be recorded on Google sheet
var TKF_URL = 'https://api.10000ft.com/api/v1/';
var TKF_AUTH = 'auth'
var TKF_PGSZ = 2500
var from = '2020-01-20'
var to = '2020-01-26'
var options = {
method: 'get',
headers: {
Authorization: 'Bearer ' + TKF_AUTH
}
};
function getUsers() {
var userarray = [];
var lastpage = false;
var page = 1;
do {
// gets 10kft data
var users = read10k_users(page);
// writes data from current page to array
for (var i in users.data) {
var rec = {};
// pushing of mandatory data
rec.id = users.data[i].id;
rec.display_name = users.data[i].display_name;
rec.email = users.data[i].email;
userarray.push(rec);
}
// checks if this is the last page (indicated by paging next page link beeing null
if (users.paging.next != null) {
lastpage = false;
var page = page + 1;
} else {
lastpage = true;
}
}
while (lastpage == false);
return (userarray);
return (userarray);
}
function read10k_users(page) {
var endpoint = 'users?';
var url = TKF_URL + endpoint + 'per_page=' + TKF_PGSZ + '&auth=' + TKF_AUTH + '&page=' + page;
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response);
//Logger.log(json.data)
return (json);
}
function showTimeData() {
var users = getUsers()
var time_array = [];
for (var i = 0; i < users.length; i++) {
// Logger.log(users[i].id)
var url = 'https://api.10000ft.com/api/v1/users/' + users[i].id + '/time_entries?fields=approvals' + '&from=' + from + '&to=' + to + '&auth=' + TKF_AUTH + '&per_page=' + TKF_PGSZ;
var response = UrlFetchApp.fetch(url, options);
var info = JSON.parse(response.getContentText());
var content = info.data;
var total_hours = 0;
for (var j = 0; j < content.length; j++) {
if (content[j].approvals.data.length > 0) {
total_hours += content[j].hours;
}
}
Logger.log('User name: ' + users[i].display_name + ' ' + 'User id: ' + users[i].id + ' ' + 'total hours: ' + total_hours+ ' ' + 'Email: ' + users[i].email)
}
}
function sendMail(showTimeData){
var emailAddress = user.email;
var message = 'Dear ' + user.display_name + 'Please update your details in the system'
var subject = ' Reminder';
MailApp.sendEmail(emailAddress, subject, message);
}
I was able to get a solution for this as follows:
for (var j = 0; j < content.length; j++) {
if (content[j].approvals.data.length > 0) {
total_hours += content[j].hours;
}
}
Logger.log('User name: ' + users[i].display_name + ' ' + 'User id: ' + users[i].id + ' ' + 'total hours: ' + total_hours + ' ' + 'Email: ' + users[i].email)
if (total_hours == 0) {
sendMail(users[i])
}
}
}
function sendMail(user) {
var emailAddress = user.email;
var message = 'Dear ' + user.display_name + 'Please update your details in the system'
var subject = ' Reminder';
MailApp.sendEmail(emailAddress, subject, message);
}

How to write if statement in JSON?

I don't know json , I have for loop statement.I need only single data , How can write if statement in JSON. Please help me,
function myFunction(response) {
var arr = JSON.parse(response);
var i;
var out = "<table>";
for(i = 0; i < arr.length; i++) {
out += "<tr><td> " +
arr[i].offerPercentage +
"</td><td>" +
arr[i].offerName +
"</td></tr>";
}enter code here
out += "</table>";
document.getElementById("id01").innerHTML = out;
}
Edit:
Now that it's clear what you want, to loop over just a single item, you change the amount of times to iterate - currently it will iterate over the whole array, to only iterate over one change arr.length to 1 (or however many items you want to display):
function myFunction(response) {
var arr = JSON.parse(response);
var i;
var out = "<table>";
for(i = 0; i < 1; i++) {
out += "<tr><td> " +
arr[0].offerPercentage +
"</td><td>" +
arr[0].offerName +
"</td></tr>";
}
out += "</table>";
document.getElementById("id01").innerHTML = out;
}
or you could simply reference the first result directly and bypass the loop which would make more sense:
function myFunction(response) {
var arr = JSON.parse(response);
var i;
var out = "<table>";
// Only append if `arr` has at least one result.
if (typeof arr[0] !== 'undefined') {
out += "<tr><td> " +
arr[0].offerPercentage +
"</td><td>" +
arr[0].offerName +
"</td></tr>";
}
out += "</table>";
document.getElementById("id01").innerHTML = out;
}
Old Answer:
Objects in Javascript don't have a .length property.
To loop over an object, use the for...in syntax:
for (var offer in arr) {
// `offer.offerPercentage` and `offer.offerName` will be available here.
}
If what's being returned is actually an array, your issue isn't your syntax, it's the fact that you are using arr[0] in each loop rather than arr[i].

Angular: Combine array objects and combine values

I'm retrieving data with http.get.
This provides me with an array of objects like below:
[{
"id”:12345,
"resource_state":2,
"external_id”:”abscdgrft”,
"upload_id”:1234567,
"athlete":{
"id”:123456,
"resource_state":2,
"firstname”:”testname”,
"lastname”:”testlastname”,
"profile_medium”:”image/athlete/medium.png",
"profile":"image/athlete/large.png",
"city”:”testcity”,
"state”:”teststate”,
…
},
"name”:”test name“,
"distance":87223.1,
"moving_time":11026,
"elapsed_time":11173,
"total_elevation_gain":682.3,
…
}]
I would like to combine all those object based on the athlete.firstname + athlete.lastname.
So for example all objects with athlete first name Jim and last name Donalds I want to be combined in one object, the same goes for all the other names.
When combining the objects based on the full name, values like "distance", "moving_time", "elapsed_time" and "total_elevation_gain" needs to be summed.
I tried using the code below but the problem is that I can't get it to work with multiple values like I mention above.
This is working only with one value, distance for example:
var obj = {}; // Initialize the object
angular.forEach(data, function(value, key) {
if (value.start_date > firstdayOfWeek && value.start_date < lastdayOfWeek) {
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
obj[value.athlete.firstname + ' ' + value.athlete.lastname] += value.distance; // Add value to previous value
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = value.distance; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
When I modify it like this it is not working anymore.
var obj = {};
angular.forEach(data, function(value, key) {
//console.log(value);
if (value.start_date > startOfLastWeek && value.start_date < endOfLastWeek) {
//console.log(value);
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
obj[value.athlete.firstname + ' ' + value.athlete.lastname] += {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add value to previous value
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
Thanks!
try to add item by item... You can't add all with += { ... }:
var obj = {};
angular.forEach(data, function(value, key) {
//console.log(value);
if (value.start_date > startOfLastWeek && value.start_date < endOfLastWeek) {
//console.log(value);
if (obj[value.athlete.firstname + ' ' + value.athlete.lastname]) { // If already exists
var aux = obj[value.athlete.firstname + ' ' + value.athlete.lastname];
aux.profile += value.athlete.profile;
aux.distance += value.distance;
...
} else {
obj[value.athlete.firstname + ' ' + value.athlete.lastname] = {
"profile" : value.athlete.profile,
"distance" : value.distance,
"moving_time" : value.moving_time,
"elapsed_time" : value.elapsed_time,
"total_elevation_gain" : value.total_elevation_gain,
}; // Add in object
}
} else {
//do nothing
}
});
console.log(obj); // Result
Use underscore or lodash groupBy, map and reduce
with lodash:
_.chain(myArr).map(function(o) {
return {
fullname: o.athlete.firstname + ' ' + o.athlete.lastname,
distance: o.distance,
moving_time: o.moving_time,
elapsed_time: o.elapsed_time,
total_elevation_gain: o.total_elevation_gain
}
}).groupBy(function(o) {
return o.fullaname
}).map(function(d, fullname) {
var totals = _.reduce(d, function(result, run, n) {
result.moving_time += run.moving_time | 0
result.elapsed_time += run.elapsed_time | 0
result.total_elevation_gain += run.total_elevation_gain | 0
return result
}, {
moving_time: 0,
elapsed_time: 0,
total_elevation_gain: 0
})
totals.fullname = fullname
return totals
})

jquery array return in function

I have a Jquery for Password-correction and it works fine, if I use the 2 Lines
// $('#minimum span').show();
// $('#minimum').addClass('boldgreen');
But I´ve tryed to put that out in a seperat function, and the return is what I want, if I alert(ret[0]);
But it doesn´t change the css in the html code.
I´ve tryed many ways, but without any result.
Any suggestions?
Thanks in advance.
var cssPassword = function(cssId, cssClass, hideShow, removeAddClass)
{
var IDKlasse = "$('" + cssId + " span')." + hideShow +"();";
var cssKlasse = "$('" + cssId + "')." + removeAddClass + "('" + cssClass + "');";
var cssArray = new Array();
cssArray[0] = IDKlasse;
cssArray[1] = cssKlasse;
return cssArray;
}
function()
...
if(passwordNew.length > 7) {
var ret = cssPassword('#minimum', 'green', 'show', 'addClass');
//eval(ret[0]);
//eval(ret[1]);
strength += 1;
alert(ret[1]);
// $('#minimum span').show();
// $('#minimum').addClass('boldgreen');
}else{
...

Resources