printing array shows different values when printing only the last element - javascript - javascript

im getting logs with a date property in the ISO YYYYMMDDhhmmss format, and im transfering them to Date object using the map function as seen below.
when I print the whole object I get the wrong dates but when I print just one element of the array its correct, this is bizarre to me,what am I missing ?
let dates = ascendingLogs.map(log => new Date(log['date'].replace(
/^(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)$/,
'$4:$5:$6 $2/$3/$1'
)));
console.log(dates[dates.length - 1])
console.log(dates)
let numberOfElements = 8
let timeGap = (dates[dates.length -1].getTime() - dates[0].getTime()) / numberOfElements;
let labels = []
for (let i = 1; i < numberOfElements; i ++){
dates[i] = new Date(dates[i - 1].getTime() + (timeGap));
};
below are the console.log of 1. last element in dates, whole dates array, ascendingLogs object
EDIT :
I have been able to narrow down the problem to the for loop, what im thinking is that it somehow asynchronously changes the console.log value but I dont know how to solve it.
heres a reproducible example you could examine :

Related

How to get previous Six months into an array

I am trying to use moment to get the previous six months, using the below code.
ngOnInit(){
let mom: moment.Moment;
var d = new Date();
let numberOfMonths=6;
let previousSIxMonths:string[]=[];
while (this.numberOfMonths > 0) {
this.previousSixMonths.push(mom.subtract(this.numberOfMonths, 'months').format('MMMM'));
this.numberOfMonths--;
console.log(this.numberOfMonths);
}
console.log(this.previousSixMonths);
}
However these cards should be displayed whenever I am on the page, and hence I have written the above code inside OnInit. Once I have all the past six months in the array, the idea is to loop over the array and display in cards. But the doesn't really work for me.
I want all my previous six months to be in an array so that I could loop across the array.
Considering this is October month, the expected output should be:
["Oct","Sept","Aug","July","June","May"]
Here is a quick way to do what you're needing:
var previousSixMonths = function(){
let n = 0;
let arRet = [];
for(; n < 6; n++)
arRet.push(moment().subtract(n, 'months').format('MMMM'));
return(arRet)
}();
console.log(previousSixMonths);

unable to get value of i in for loop

I have a simple for loop and it is matching condition according to my log files
but still the value of i is showing undefined
here is my javascript code
var indexs,i;
for(i = 0; i < data[0].length; i++){
if (new Date(data[0][i]) == new Date(inRecord.rdate))
{indexs = i;
}
Logger.log(new Date(data[0][i])+ " : " +new Date(inRecord.rdate) +": indexes:"+indexs)
}
and Image below if my log output which shows the condition should matched.
what am I doing wrong here?
new Date returns an object. And two objects can not be compared even where they contain the same data. The result will always be false.
new Date creates an object which cannot be compared. Even if two of these objects are identical, they will not produce a true comparison. To get around this, define them before the IF statement and compare the millsecond values with getTime(). This will be comparing two numbers (not objects) and work great :)
let dataDate = new Date(data[0][i])
let recordDate = new Date(inRecord.rdate)
if (getTime(dataDate) == getTime(recordDate)) {
indexs = i;
}
Happy to clarify if this doesn't work.

API response is returning undefined

I am making a API call that returns a JSON response of an Array with a bunch of objects. Each object has a key "dt" that is the timestamp of a specific time of day and another key of "height" which is the Ocean's predicted or past tide height at that moment in time.
I only want the current tide's height at whatever moment in time the AJAX call happens. This is the function I created in order to achieve that:
let tideApi = 'https://www.worldtides.info/api?heights&lat=45.202&lon=-123.963&key=24e4ff14-6edf-4f79-9591-e47f9e0e21e1';
$.getJSON(tideApi, function(response) {
// Create Global variable
let tideHeight = 0;
// get current time
let nowMil = new Date().getTime();
// round that time to the nearest halfhour and convert back to timestamp (JSON timestamps are set in intervals of 30 minutes)
let timeNow = Math.round(nowMil/1000/60/30) * 30 * 60 * 1000;
// set entire array to variable
let heightArray = response.heights;
// get length
len = heightArray.length
// loop through each object in height array
for (var i=0; i < len; i++) {
// if one of the objects timestamp equals current time
if (i.dt = timeNow) {
// set tide height to variable
tideHeight = i.height;
// return tide height (curretly returning undefined)
console.log("Tide Height: " + tideHeight);
return tideHeight;
} else {
console.log("Error, no time found");
}
}
// put tide height into div
$("#tideStat").append("<p>" + tideHeight + "</p>");
});
It's currently returning undefined for a reason I am struggling to figure out. Any help would be great!
API Call (Don't worry going to change after this)
Codepen
There are a few problems in your code
let timeNow = Math.round(nowMil/1000/60/30) * 30 * 60 * 1000;. Your API doesn't seem to be returning milliseconds. Remove the * 1000.
You're not accessing items from your heightArray. Rather, just checking dt and height property on i, which is an integer. So change i.dt and i.height to heightArray[i].dt and heightArray[i].height respectively.
When you use if (lhs = rhs), you're attempting to assign, not compare. So, change = to === in the if condition.
Remove return tideHeight;. I think you want break? Not sure though. Because of this line, your last jQuery related code doesn't execute.
Forked pen. Some logs commented out for better output.
Use bracket notation to reference i object of heightArray array, === operator, instead of =, which is assignment operator
if (heightArray[i].dt === timeNow) {
// do stuff
tideHeight = heightArray[i].height;
}

MomentJS possible bug with the add() function

I'd like to add several months in an array but I cannot get the add() function of MomentJS to work properly. Here's how it goes :
function getMonths(begin, end){
var cursor = moment(begin);
var momentEnd = moment(end);
var arrayMonths = [];
while(cursor.month() != momentEnd.month() || cursor.year() != momentEnd.year()){
cursor.add(1, 'month'); // Actually adds one month to the cursor
console.log(cursor.toDate()); // Because this display the cursor with an added month
arrayMonths.push(cursor.toDate()); // However the cursor being pushed doesn't have this added month
console.log(arrayMonths); // verified here
}
return arrayMonths;
}
The console log shows that the cursor has actually been incremented (as add() is a mutator) however its proper value isn't added to the array.
I cannot figure out if this is an issue in my code or if it is inherent to MomentJS. Does anybody have any clue ?
Thank you !
The documentation for toDate says:
To get the native Date object that Moment.js wraps, use moment#toDate.
This will return the Date that the moment uses, so any changes to that Date will cause the moment to change. If you want a Date that is a copy, use moment#clone before you use moment#toDate.
IE you're getting the same underlying Date object every time you call toDate - ie each call to add is also modifying it, and every member of the array is actually the same object.
If you do as the documentation says, and use clone, your code works:
arrayMonths.push(cursor.clone().toDate());
Here's a demo:
function getMonths(begin, end){
var cursor = moment(begin);
var momentEnd = moment(end);
var arrayMonths = [];
while(cursor.month() != momentEnd.month() || cursor.year() != momentEnd.year()){
cursor.add(1, 'month'); // Actually adds one month to the cursor
console.log(cursor.toDate()); // Because this display the cursor with an added month
//clone the object before pushing, to ensure it's not further modified
arrayMonths.push(cursor.clone().toDate());
console.log(arrayMonths); // verified here
}
return arrayMonths;
}
getMonths(moment('2016/01/01', 'YYYY/MM/DD'), moment('2017/01/01', 'YYYY/MM/DD'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.13.0/moment.js"></script>
Not entirely sure what's happening here as your code looks OK.
I would however try using and temporary variable to double check what's happening.
function getMonths(begin, end){
var cursor = moment(begin);
var momentEnd = moment(end);
var arrayMonths = [];
while(cursor.month() != momentEnd.month() || cursor.year() != momentEnd.year()){
cursor.add(1, 'month');
var cursorDate = cursor.toDate();
console.log(cursorDate); // temporary variable - no chance it gets mutated etc...
arrayMonths.push(cursorDate);
console.log(arrayMonths);
}
return arrayMonths;
}

Cannot read property "0" from undefined. Error Google Apps Script

I´m geting Cannot read property "0" from undefined. Error on line 16. ( while (colunaDias[emptyCell][0] <= dias) )
It should be a very simple function for google SpreadSheets. I can´t see what I´m doing wrong...
The bizarre thing is that if I don´t use the variable "dias" and use a integer instead. The while function works....
function myFunction() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var leadsSheet = ss.getSheetByName("Leads Todas as Categorias, menos outros - Days (5days)");
var targetSheet = ss.getSheetByName("feticaria");
var cellLeads = leadsSheet.getRange(1,1).getValue();
//var cellTarget = targetSheet.getRange(1,1).setValue(valor);
var colunaDias = leadsSheet.getRange('B:B').getValues();
var sourceMedium = leadsSheet.getRange('A:A').getValues();
var emptyCell = 16;
var dias = 1;
while (colunaDias[emptyCell][0] != ""){
while (colunaDias[emptyCell][0] <= dias){
dias++;
emptyCell++;
}
emptyCell++;
}
Logger.log(emptyCell);
}
I think the only thing that could cause that error is if emptyCell is bigger than the colunaDias array, i.e. if your sheet is smaller than 16 rows (if the value you show here is correct).
Add this line right before the first while :
Logger.log('emptyCell = '+emptyCell+' and colunaDias.length = '+colunaDias.length);
I tested a copy of your script and it runs without error except if I define emptyCell > 1000 on a 1000 rows Sheet.
I'm guessing that colunaDias[emptyCell] is undefined. It passes the first while condition, because "undefined" is not equal to "". If colunaDias[emptyCell] is undefined, then either there is something wrong with this line:
var colunaDias = leadsSheet.getRange('B:B').getValues();
or
colunaDias[emptyCell][0]
Where "emptyCell" is 16 is the problem. getValues() returns an object of rectangular grid of values. I would test to see if there is anything in the rectangular grid, by checking [0][0].
Logger.log('is there any data? ' + colunaDias[0][0])
If there is no data, then the something failed on line:
var colunaDias = leadsSheet.getRange('B:B').getValues();
If that line is working, then something higher up is wrong.
You should be checking the return type of getSheetByName for null.
// The code below will log the index of a sheet named "YourSheetName"
var leadsSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("YourSheetName");
if (leadsSheet != null) {
Logger.log(leadsSheet.getIndex());
}
I know this post in from a few years ago, but this was the closest to a problem I am having. I just want to post my answer in case someone else ends up here one day.
For some reason the check variable "dias" is being passed as a string.
That's why replacing it with a number allows the script to run.
dias = parseInt(dias); //use this before the variable needs to be read
I cant say why it is passing a string after being ++ but this will fix it

Categories

Resources