Why is my If-Else statement defaulting to "else"? - javascript

I'm new to JavaScript and have just been toying with this little IF-ELSE exercise. Essentially, slots 1 thru 4 are static to experiment with the || operator. The const 'testSlot' is one that I've altered as time passes to try and execute the "else if" segment of my code; e.g, if it's 9:10 PM I've
just been manually changing the getHours to 21 and the getMinutes to 10 and then run the code.
With that said, I can't get either of the first two console.logs to run, it always just runs the "else", which is three.
My question is mostly if my usage the of the date object was wrong or if the syntax in my If-Else statement was wrong. A pointer in the right direction would be very much appreciated.
Here is my code:
const now = new Date();
const slot1 = now.getHours === 12 && getHours.getMinutes === 1;
const slot2 = now.getHours === 12 && getHours.getMinutes === 2;
const slot3 = now.getHours === 12 && getHours.getMinutes === 3;
const slot4 = now.getHours === 12 && getHours.getMinutes === 4;
const testSlot = now.getHours === 20 && getHours.getMinutes === 34;
if (slot1 || slot2 || slot3 || slot4) {
console.log('one');
} else if (testSlot) {
console.log('two');
} else {
console.log('three');
};

.getHours() and .getMinutes() are both functions and require parenthesis after. Also, getHours.getMinuets() wouldn't do anything. You have to do now.getMinutes(). I updated your snippet for you. It will still console.log three but that's only because all the if statements are false. Wait till its 12:01 and it should say one.
const now = new Date();
const slot1 = now.getHours() === 12 && now.getMinutes() === 1;
const slot2 = now.getHours() === 12 && now.getMinutes() === 2;
const slot3 = now.getHours() === 12 && now.getMinutes() === 3;
const slot4 = now.getHours() === 12 && now.getMinutes() === 4;
console.log(now.getHours());
console.log(now.getMinutes());
const testSlot = now.getHours() === 20 && now.getMinutes() === 34;
if (slot1 || slot2 || slot3 || slot4) {
console.log('one');
} else if (testSlot) {
console.log('two');
} else {
console.log('three');
};

Related

Javascript refactroing series of if else statement

I have a method and attached an event listener like below.
This method looks ugly. Is there any other way to refactor?
Any suggestions or ideas would be appreciated.
document.querySelector('dateInput').addEventListener('input', func.validateCalendar, false);
const func = {
validateCalendar({target}){
const tmpArr = Array.from(target.value.replace(/[^0-9\.]/g, ''));
if( tmpArr.length === 0 ){
target.value = '';
}else if( tmpArr.length === 4){
target.value = tmpArr.join('');
}else if( tmpArr.length === 5 ){ //month first digit
const month1 = +tmpArr[4]
console.log('len:5, month1: ', month1);
if( month1 > 1 ){
tmpArr.splice(4,1, '');
}
tmpArr.splice(4,0, '-');
target.value = tmpArr.join('');
}else if( tmpArr.length === 6){ //month second digit
const month1 = +tmpArr[4];
const month2 = +tmpArr[5];
const cond1 = month1 === 0 && month2 === 0;
const cond2 = month1 === 0 && month2 > 9;
const cond3 = month1 === 1 && month2 > 2
if( cond1 || cond2 || cond3 ){
tmpArr.splice(5,1, '');
}
tmpArr.splice(4,0, '-');
target.value = tmpArr.join('');
}else if( tmpArr.length === 7 ){ //day first digit
const month = +tmpArr.slice(4,6).join('');
const day1 = +tmpArr[6];
console.log('len 7 : day1 ', day1);
const cond1 = month !== 2 && day1 > 3;
const cond2 = month === 2 && day1 > 2
if( cond1 || cond2 ){
tmpArr.splice(6,1, '');
}
tmpArr.splice(4,0, '-')
tmpArr.splice(7,0, '-');
target.value = tmpArr.join('');
}else if( tmpArr.length === 8 ){ //day second digit
const year = +tmpArr.slice(1,4).join('');
const month = +tmpArr.slice(4,6).join('');
const day = +tmpArr.slice(6,8).join('');
const monthsIn31 = [1, 3, 5, 7, 8, 10, 12];
const monthsIn30 = [4, 6, 9, 11];
const cond1 = day === 0;
const cond2 = monthsIn31.includes(month) && day > 31;
const cond3 = monthsIn30.includes(month) && day > 30;
const cond4 = month === 2;
if( cond1 || cond2 || cond3){
tmpArr.splice(7,1, '');
}
if( cond4 ){
const cond1 = moment([year]).isLeapYear() && day > 29;
const cond2 = !moment([year]).isLeapYear() && day > 28
if( cond1 || cond2 ){
tmpArr.splice(7,1, '');
}
}
console.log('len 8 : ', target.value);
tmpArr.splice(4,0, '-')
tmpArr.splice(7,0, '-');
target.value = tmpArr.join('');
}else if( tmpArr.length > 8 ){
target.value = target.value.slice(0, -1);
}
},
}
You can try switch..case if you just check a variable again and again.
Thus if you currently have:
var a = 5
if(a === 5){
console.log("Five");
} else if(a === 7) {
console.log("Seven");
} else if (a === 9) {
console.log("Nine");
}
// ... and so on
else {
console.log("Irrelevant");
}
This is equivalent switch..case for it
var a = 5
switch(a) {
case 5:
console.log("Five");
break;
case 7:
console.log("Seven");
break;
// ... and so on
default:
console.log("Irrelevant");
}
However, meanwhile the if..else if uses curly brackets {} to limit the scope of the condition, switch..case uses break to limit it. The default in the switch..case is equivalent to the else in if..else, if and only if you put the break properly.
If you forget to put break, it will execute every cases placed under the satisfied condition until it finds the break or return or the default or the closing curly bracket } of the switch..case statement.

javascript imports are real-time?

well, i'm trying to do a snake game using basic imports, but at some time, i got stuck, because of a javascript assignment.
i assigned the value the oldSnake as the value of the snake before its changes.
but as i get into the forEach, the value already assigned changes and i don't know why.
Before getting into the forEach
After getting into the forEach
i searched about it, and didn't get anywhere, Does someone know what's happening?
import { snake } from "/snake.js";
let lastDirection = {y: 1, x:0};
export function updateGame(direction){
let oldSnake = snake;
if (!(direction.y == 0 && direction.x == 0)){
if((lastDirection.y == 1 && direction.y == -1 || lastDirection.y == -1 && direction.y == 1)
||(lastDirection.x == 1 && direction.x == -1 || lastDirection.x == -1 && direction.x == 1)){
direction = lastDirection;
}
snake.forEach((snakeSlice, index)=>{
lastDirection = direction;
if (index === 0){
snakeSlice.ypos+= direction.y;
snakeSlice.xpos+= direction.x;
}
else{
snakeSlice.ypos = oldSnake[index-1].ypos;
snakeSlice.xpos = oldSnake[index-1].xpos;
}
});
}
}

Making flags with conditions using Pentaho/JavaScript

I'm trying to optimize my code with a better way to do this.
I have a variable "hour". I need to make flags like this:
if (hour == 0) {flag12AM = 'yes'}
else {flag12AM == 'no'}
if (hour == 0 || hour == 1) {flag1AM = 'yes'}
else {flag1AM == 'no'}
if (hour == 0 || hour == 1 || hour == 2) {flag2AM = 'yes'}
else {flag2AM == 'no'}
[...]
if (hour == 0 || hour == 1 [...] || hour == 23) {flag23PM = 'yes'}
else {flag23PM == 'no'}
Could I use a loop to do that? I'm using Pentaho, so, if there's any step that do this job, please, let me know.
Thanks!!
Maybe this will be useful for you:
var h = 20;
[...Array(24).fill().map((v, i) => i + 1)]
.forEach((v) =>
console.log([...Array(v).fill().map((h, i) => i)]
.reduce((result, currentValue) => result || (h == currentValue), false), v))
You can use a data grid step to generate all flag values and then look up the hour and retrieve all flags.
IIUC, using Modified Java Script Value step, you can calculate all the flags with a for loop and then assign and export the values to specific flag names
var flags = []
for (i=0; i<24; i++) {
flags[i] = hour <= i ? "yes" : "no"
}
var flag12AM = flags[0]
var flag1AM = flags[1]
var flag2AM = flags[2]
....
var flag23PM = flags[23]
Or use Scripting -> Formula step
New field: flag12AM
Formula: IF([hour]<=0;"yes";"no")
Value type: String
do the similar to all other fields.

Form date (yyyy-mm-dd) validation.

In my validation file i have a "prepare Data" function that saves to data from the DOM into a JSON and returns it as data.applicants.occupation_since:
applicants.occupation_since = mainAppContainer.find(".employmentPeriodStart").val()
And then validates it in a "validate" function:
var validateOccupationCompany, validateOccupationSince;
if (data.applicants[0].occupation === 'full_time' || data.applicants[0].occupation === 'hourly' || data.applicants[0].occupation === 'part_time' || data.applicants[0].occupation === 'finite_time') {
validateOccupationCompany = true;
validateOccupationSince = true;
}
var dateVal, dateValues, dtDay, dtMonth, dtYear, isleap, validatePattern;
if (validateOccupationSince) {
dateVal = data.applicants[0].occupation_since;
validatePattern = /^(\d{4})(\/|-)(\d{1,2})(\/|-)(\d{1,2})$/;
dateValues = dateVal.match(validatePattern);
dtYear = dateValues[1];
dtMonth = dateValues[3];
dtDay = dateValues[5];
if (validatePattern.test(dateVal) !== true) {
ret.status = false;
ret.errorMessages.push("SOME ERROR MSG");
ret.errorClasses.push(".employmentPeriodStart");
} else if (dtMonth < 1 || dtMonth > 12) {
ret.status = false;
ret.errorMessages.push("SOME ERROR MSG.");
ret.errorClasses.push(".employmentPeriodStart");
} else if (dtDay < 1 || dtDay > 31) {
ret.status = false;
ret.errorMessages.push("SOME ERROR MSG.");
ret.errorClasses.push(".employmentPeriodStart");
} else if ((dtMonth === 4 || dtMonth === 6 || dtMonth === 9 || dtMonth === 11) && dtDay === 31) {
ret.status = false;
ret.errorMessages.push("SOME ERROR MSG.");
ret.errorClasses.push(".employmentPeriodStart");
} else if (dtMonth === 2) {
isleap = dtYear % 4 === 0 && (dtYear % 100 !== 0 || dtYear % 400 === 0);
if (dtDay > 29 || (dtDay === 29 && !isleap)) {
ret.status = false;
ret.errorMessages.push("SOME ERROR MSG.");
ret.errorClasses.push(".employmentPeriodStart");
}
}
}
I've been stuck trying to make it work for sometime and haven't been able to solve it, and it looks kind of messy atm.
An alternative solution is fine, or if you could point me in the right direction.
We've also been struggling with Date, Time and DateTime and its formats.
I would strongly recommend to use MomentJs.
For date (yyyy-mm-dd) validation you can use this RegEx.pattern.test(input) returns True if date has the same format as you want. Demo
var input = '1997-01-01';
var pattern =/^([0-9]{4})\-([0-9]{2})\-([0-9]{2})$/;
alert(pattern.test(input));
Then, you can validate like this. Demo
var invalidDate = '2011-30-02';
var comp = invalidDate.split('-');
var m = parseInt(comp[1], 10);
var d = parseInt(comp[2], 10);
var y = parseInt(comp[0], 10);
var date = new Date(y,m-1,d);
if (date.getFullYear() == y && date.getMonth() + 1 == m && date.getDate() == d) {
alert('Valid date');
} else {
alert('Invalid date');
}
I Hope it helps

trying to loop through an array where the elements are object

I'm wondering why the code outputs false when you can see in the object that Wednesday = 34. I think i might have problems with changing the i variable.
var lookup = [{"Monday" : 12}, {"Wednesday" : 34},{"Thursday" : 0},{"Saturday" : 56} ]
// console.log(lookup[1]["Wednesday"] == 34) // prints out true
function ami(day, num){
var a;
for(var i = 0; i < lookup.length; i++){
if(lookup[i][day] == num ||
day == "Tuesday" && num >95 ||
day == "Friday" && num %2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666){
a = true
}else{
a = false
}
}
return a;
}
console.log(ami("Wednesday", 34))
You are rewriting the value of a with each iteration of the for loop. In essence, what you are doing is checking the last item of the lookup array, since the previous results are always overwritten.
I don't know exactly what you're trying to achieve with the conditions, but this could be what you need:
function ami(day, num){
for(var i = 0; i < lookup.length; i++){
if(lookup[i][day] == num ||
day == "Tuesday" && num >95 ||
day == "Friday" && num %2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666){
return true;
}
}
return false;
}
When your code reaches i=1, a gets indeed set to true. But after that the loop is allowed to continue, so when i gets incremented to 2, a gets set to false again.
You can fix this by returning from the function as soon as you determine the return value should be true:
var lookup = [{"Monday" : 12}, {"Wednesday" : 34},{"Thursday" : 0},{"Saturday" : 56} ]
function ami(day, num){
for(var i = 0; i < lookup.length; i++){
if(lookup[i][day] == num ||
day == "Tuesday" && num >95 ||
day == "Friday" && num %2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666){
return true;
}
}
}
console.log(ami("Wednesday", 34));
You can simplify the code even further if you use an ordinary object as your lookup table:
var lookup = {"Monday" : 12, "Wednesday" : 34, "Thursday" : 0, "Saturday" : 56};
function ami(day, num){
return (lookup[day] == num ||
day == "Tuesday" && num >95 ||
day == "Friday" && num %2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666);
}
console.log(ami("Wednesday", 34));
A Array.some() should do it.
var lookup = [{ "Monday": 12 }, { "Wednesday": 34 }, { "Thursday": 0 }, { "Saturday": 56 }];
function ami(day, num) {
return lookup.some(function (a) { return a[day] === num; }) ||
day == "Tuesday" && num > 95 ||
day == "Friday" && num % 2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666
}
document.write(ami("Wednesday", 34));
The other possibillity is to optimise the lookup array to an object with more than one property, like
var lookup = { "Monday": 12, "Wednesday": 34, "Thursday": 0, "Saturday": 56 };
The other version is this. I took your code and changed the behaviour of the condition and the loop condition as well. So the given conditions are first evaluated and then if necessary the iteration over the array. The variable a is taken as well as indicator to stop the iteration as well as the return value.
var lookup = [{ "Monday": 12 }, { "Wednesday": 34 }, { "Thursday": 0 }, { "Saturday": 56 }];
function ami(day, num) {
var a = false;
if (day == "Tuesday" && num > 95 ||
day == "Friday" && num % 2 == 0 ||
day == "Sunday" && num == 666 ||
day == "Sunday" && num == -666) {
a = true;
}
for (var i = 0; !a && i < lookup.length; i++) {
a = lookup[i][day] == num;
}
return a;
}
document.write(ami("Wednesday", 34));

Categories

Resources