Run loop array in order - arrays

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.

Related

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

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();
});
}

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 have dynamic rowspan with antd react

I am trying to prepare a table with dynamic rowspan in antd(data will be dynmaic)
I have data like below.
Wanted to display as below. Can you please help ?
[{"col1":"temp1","col2":"1","col3":"x"},
{"col1":"temp1","col2":"1","col3":"y"},
{"col1":"temp1","col2":"2","col3":"z"},
{"col1":"temp2","col2":"3","col3":"a"}];
we can write custom render method to resolve this issue.
sample :
render: (value, row, index) => {
const obj = {
children: value,
props: {},
};
if (index >= this.state.branch_new_index) {
for (let i = 0; index + i !== metrics.length
&& value === metrics[index + i].branch &&
metrics[index].product === metrics[index + i].product; i += 1) {
obj.props.rowSpan = i + 1;
this.state.branch_count = i + 1;
}
this.state.branch_new_index = index + this.state.branch_count;
if (index + 1 >= metrics.length) {
this.state.branch_new_index = 0;
}
} else {
obj.props.rowSpan = 0;
if (index + 1 >= metrics.length) {
this.state.branch_new_index = 0;
}
}
return obj;
},

Avoid message repeating?

I need some help here I have a code that shows a message being updated per 2 seconds but I want a single message that replaces itself.
let channel = guild.channels.find(channel => channel.name === guilds[guild.id].digitchan);
let channel2 = guild.channels.find(channel => channel.name === guilds[guild.id].countdownchan);
if (channel && channel2) {
channel.send(embed);
scrims[guild.id] = {
timer: setTimeout(function() {
channel2.join().then(connection => {
const dispatcher = connection.playFile('./Audio/test.mp3');
console.log('dispatcher');
console.log(dispatcher == null);
dispatcher.on('end', () => {
channel2.leave();
const embed2 = new RichEmbed()
.setColor(0xc1d9ff)
.addField("message x", false);
channel.send(embed2);
scrims[guild.id].codes = true;
scrims[guild.id].codedata = {};
scrims[guild.id].playerinterval = setInterval(function() {
const embed4 = new RichEmbed()
.setColor(0xc1d9ff)
.setTitle("codes:");
Object.keys(scrims[guild.id].codedata).forEach(function(key) {
let codeobj = scrims[guild.id].codedata[key];
let user_str = "";
Object.keys(scrims[guild.id].codedata[key]).every(function(key2, count) {
let user = scrims[guild.id].codedata[key][key2];
user_str = user_str + user + "\n"
if (count >= 15) {
if (count > 15) user_str = user_str + "and more";
return false;
};
})
embed4.addField(key + " (" + Object.keys(codeobj).length + " codes)", user_str, true);
})
channel.send(embed4);
}, 2000);
scrims[guild.id].timer2 = setTimeout(function() {
scrims[guild.id].codes = false;
clearInterval(scrims[guild.id].playerinterval);
const embed3 = new RichEmbed()
.setColor(0xc1d9ff)
.setTitle("codes:");
Object.keys(scrims[guild.id].codedata).forEach(function(key) {
let codeobj = scrims[guild.id].codedata[key];
let user_str = "";
Object.keys(scrims[guild.id].codedata[key]).every(function(key2, count) {
let user = scrims[guild.id].codedata[key][key2];
user_str = user_str + user + "\n"
if (count >= 15) {
if (count > 15) user_str = user_str + "y mas..";
return false;
};
})
embed3.addField(key + " (" + Object.keys(codeobj).length + " codes)", user_str, true);
})
channel.send(embed3);
}, 1 * 60000);
});
});
}, time * 60000);
};
};
This is the discord action:
Codes:
Codes:
Codes:
Codes:
Codes:
Codes:
Codes:
Codes: 3c5
Codes: 3c5
So could be some kind of message deleting before sending the same message updated again, please let me know how to do it or some kind of code changing.
Just use message.edit() to edit the message.
message.edit() on discord.js docs

Formatting numbers in Angular.js

I have a variable in Angular.js that I should fill like that :
values.push({x: '' + d.x + 'h', y: d.y / 100})
d.x and d.y are numbers that I should display in a ndv3 multiBarChart.But I should format the numbers as if I have 2500, I obtain 2 500.How can I do it ?
I write Angularjs filters Example.jsfiddle
HTML File
<div>
<label >{{"4876931.19" | numberFilter}}</label>
</div>
App Js
angular.module('myApp', ['filters']);
Filter js
angular.module('filters', []).filter('numberFilter', [function () {
return function (number) {
if (!angular.isUndefined(number)) {
var parts = number.split(".");
var str = parts[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ");
if(parts[1] !== undefined){
str+="."+parts[1];
}
return str;
}
};
}]);
Updated Code
Here is a small Javascript function which parses the provided number and format it to the desired output:
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
Calling this function with the provided number:
formatNumber(4876931.19) // output will be: 4 876 931.19
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
console.log(formatNumber(4876931.19))

Resources