How to get Functions output and re-use within IF/else Statement - javascript

I have function at the bottom of my script which counts for how many tools were used.
Then based on how many tools were used I want to perform different actions.
I can easily check the output of the Function but I struggle to put it into If statement.
How to get Functions output and re-use it within IF Statement?
var HowManyTools = HowManyTools1();
if (HowManyTools <= 2) {
Category13();
} else if (HowManyTools >= 6) {
Category14();
} else if (HowManyTools > 2) {
Category12();
}
function HowManyTools1() {
//returns value between 1-9
}
Update: I've added if to the last else. It executes the Category13();. Without if all previous statements were simply false so it went straight to the last statement with Category12();
I can output into Category13/ Category12. But not the Category14.
It seems like my function can't get defined, as soon as I put it within a variable, and if I try to alert(HowManyTools) I simply get undefined Error.
Tried a few examples from here but to no avail

This variant should demonstrate that every one of your Category functions will run if its if-condition is met.
I pass HowManyTools to each of those functions for demonstration purposes.
for (var i = 0; i < 20; i++) {
test();
}
function test () {
var HowManyTools = HowManyTools1();
if (HowManyTools <= 2) {
Category13(HowManyTools);
} else if (HowManyTools >= 6) {
Category14(HowManyTools);
} else if (HowManyTools > 2) {
Category12(HowManyTools);
}
}
function HowManyTools1() {
return Math.floor(Math.random() * 9 + 1);
}
function Category12(val) {
console.log(`Category 12: value = ${val}`);
}
function Category13(val) {
console.log(`Category 13: value = ${val}`);
}
function Category14(val) {
console.log(`Category 14: value = ${val}`);
}

Related

How to use setInterval() to call a click function periodically within another function?

this is my first programming in Java. I have two functions, #start and #reset. I want to use setInterval to use #reset function within #start after every 10 seconds.
Here are the two functions. First is #start
$('#start').click(function() {
// Calculate the amount of time in milliseconds to run for
var timeleft_s = Math.round(
parseInt($('#hours' ).val())*3600 +
parseInt($('#minutes').val())*60 +
parseInt($('#seconds').val())*1
);
if (timeleft_s > 2147483647) { // Max unsighed 32 bit value
alert("That's too long. Pick a shorter time.");
return;
}
if (APP.last_sent_status !== null && APP.last_sent_status !== APP.status) {
return false;
}
// 0 : not started
// 1 : running
// 2 : stopped
switch(APP.status) {
case 0:
APP.resumeMCA(APP.channel, timeleft_s);
APP.last_sent_status = 1;
break
case 1:
APP.stopMCA(APP.channel);
APP.last_sent_status = 2;
break
case 2:
APP.resumeMCA(APP.channel, timeleft_s);
APP.last_sent_status = 1;
break
default:
break
}
APP.updateButtonStates();
});
Here is the reset function
$('#reset').click(function() {
APP.resetHistogram(APP.channel);
});
I want to use setInterval inside the start function make sure the reset function executes after every 10 seconds.
Here is what I have tried so far with no luck. Any help is appreciated:
$('#start').click(function() {
// Calculate the amount of time in milliseconds to run for
var timeleft_s = Math.round(
parseInt($('#hours' ).val())*3600 +
parseInt($('#minutes').val())*60 +
parseInt($('#seconds').val())*1
);
if (timeleft_s > 2147483647) { // Max unsighed 32 bit value
alert("That's too long. Pick a shorter time.");
return;
}
if (APP.last_sent_status !== null && APP.last_sent_status !== APP.status) {
return false;
}
// 0 : not started
// 1 : running
// 2 : stopped
switch(APP.status) {
case 0:
APP.resumeMCA(APP.channel, timeleft_s);
APP.last_sent_status = 1;
break
case 1:
APP.stopMCA(APP.channel);
APP.last_sent_status = 2;
break
case 2:
APP.resumeMCA(APP.channel, timeleft_s);
APP.last_sent_status = 1;
break
default:
break
}
setInterval(#reset,10000)
APP.updateButtonStates();
});
function resetFunction(){
APP.resetHistogram(APP.channel);
}
$('#reset').click(resetFunction);
then replace
setInterval(#reset,10000) with
setInterval(resetFunction,10000)
since you defined the function to be called on #reset click as anonymous there's no reference as such by which you can call it.
so you define it by giving it a name, and then use that in place of onclick function as well as inside your start function
I am not totally sure of this answer. If you are trying to start a setInterval inside of the onclick of #start, here's what I think you could do:
setInterval(() => $("#reset").onclick(),10000);

Can pass a conditional statement as a function argument?

I have a main function and want to control 2 actions with it. Thereby I pass different variables to the function.
My question is whether I can also pack the condition of an If query into a variable.
For the one action I want to have CurrentImageNumber <= 3 as an if argument and for the other action CurrentImageNumber >= 2 in the if query.
The code would look something like this:
function imageChange() {
CurrentImageNumber = parseInt(CurrentImageID.slice(-1)) // not a static value
if (b) {
// Some fancy Code where var a is used
}
else {
// Some fancy Code where var c is used
}
}
document.getElementById('button-1').onclick = function() {
imageChange(a = 1, b = CurrentImageNumber <= 3, c = -3)
}
document.getElementById('button-2').onclick = function() {
imageChange(a = -1, b = CurrentImageNumber >= 2, c = 2)
}
Yes you could do this, but what actually happens is, the condition is checked and the predicate returns a boolean value which is parsed into the function.
This would be done like so:
doStuff(CurrentImageNumber <= 4);
function doStuff(a) {
if (a) {
// Execute some fancy code
}
}
But what actually happens during runtime is equivalent to this:
Lets say CurrentImageNumber == 0:
const predicateResult = CurrentImageNumber <= 4;
// Here predicateResult is of type boolean and is true
doStuff(predicateResult);
function doStuff(a) {
if (a) {
// Execute some fancy code
}
}
The function needs a parameter variable to get the argument.
doStuff(CurrentImageNumber >= 2)
doStuff(CurrentImageNumber <= 4)
function doStuff(a) {
if (a) {
// execute some fancy code
}
}

How to test js factory function using mocha & chai

I am trying to test my DOM project, so it should make sure that the cost is 2.75 and sms is 0.75. It returns an assertion error that says expected 2.75 to equal undefined. I need help
accessing the correct values of call and sms.
Here's my factory function
var callCost = 0;
var smsCost = 0;
var totalCost = 0;
const warning = 30;
const critical = 50;
function getCall() {
return callCost;
}
function getSms() {
return smsCost;
}
function getTotal() {
totalCost = callCost + smsCost;
return totalCost;
}
function radioButtons(selectedBill) {
if (selectedBill === "call") {
callCost += 2.75;
} else if (selectedBill === "sms") {
smsCost += 0.75;
}
}
function totalClassName() {
if (getTotal() >= warning && getTotal() < critical) {
return "warning";
} else if (getTotal() >= critical) {
return "critical";
}
}
return {
getCall,
getSms,
getTotal,
radioButtons,
totalClassName
}
}
describe('The radio-bill function', function(){
it('Should be able to add call at 2.75', function(){
var itemType = RadioBill();
itemType.radioButtons("call");
assert.equal(2.75, itemType.radioButtons("call"))
})
})
You only need to change your assert line to get your test working.
var itemType = RadioBill();
itemType.radioButtons("call");
assert.equal(itemType.getCall(), 2.75);
Here, the first thing to note is that the order of the arguments in a call to assert does matter. The first argument is the actual value, the second one is the expected value. Typically, but not always the actual value will be the result of an operation, and the expected value will be constant.
The second point is that in your code the function radioButtons does not return a value, it just changes the value of an internal state variable. But there is already the function getCall to get that value, and that is what the assert line is checking.

break from while loop from anonymous function

I am new to javascript, my background is python and ruby and I am having issues dealing with javascript anonymous functions, my problem is the following:
I have an element in the page which has an attribute value (true/false), I need to keep performing an action until this attribute changes value.
the code that I tried out is below, as you could guess, the break won't quit the loop if result.value == true... Any idea if I am in the right direction?
var counter = 0;
while (counter < 5) {
this
.click('#someelementid')
counter++;
this
.getAttribute('#someelementid', 'disabled', function(result) {
if (result.value == 'true') {
this.break;
}
}.bind(this));
this.api.pause(1000);
};
My assumption is that by binding this, I have access to the while block? Please correct me if I am wrong.
Have you tried changing your code to something like below ?
var counter = 0;
var arr = [1, 2, 3, 4, 5];
while (counter < 5) {
arr.forEach(
(element) => {
if (counter < 5) { // if you don't have this it will print all 5, else it prints only 3
console.log('Element value:', element);
}
if (element == 3) {
counter = 5;
}
}
);
}
What happens is this:
When you enter the while loop it will enter the forEach loop and start iterating, when it reaches element == 3 it will set counter to 5, but it still has to finish the current forEach loop, once it does it wont perform another while loop therefore exiting it.
So changing your code to:
var counter = 0;
while (counter < 5) {
this
.click('#someelementid')
counter++;
this
.getAttribute('#someelementid', 'disabled', function(result) {
if (result.value == 'true') {
counter = 5; // This should do the trick (without 'this')
}
}.bind(this));
this.api.pause(1000);
};
The break inside a function would not break the loop outside the function.
Through getAttribute() get the result inline instead of having a callback. then you can break the function.
Or
Have a global variable. breakLoop = false; set it to true; inside the callback function. And put a check on this variable in the while loop. while(!breakLoop ..)
Another approach.
Don't have a loop altogether.
var counter = 0;
function doSomething(){
this.click('#someelementid');
counter++;
this.getAttribute('#someelementid', 'disabled', function(result) {
if(result.value != 'true' && counter<5){
this.api.pause(1000);
doSomething();
}
}.bind(this);
};

how to check the presence of the element in the array?

please help solve the problem.
live example is here: https://jsfiddle.net/oqc5Lw73/
i generate several tank objects:
var Tank = function(id) {
this.id = id;
Tank.tanks.push(this);
}
Tank.tanks = [];
for (var i = 0; i < 3; i++) {
new Tank(i);
}
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
after i delete tank with random index:
var tankDel = Math.floor(Math.random() * (3));
Tank.tanks.splice(tankDel, 1);
Tank.count -= 1;
Tank.tanks.forEach(function(tank, i, arr) {
console.log(tank);
});
console.log('summary tanks: ' + Tank.tanks.length);
i try check tanks massive. if tanks massive contain tank with property 'id' = 0 then i need display alert('tank with id 0 is dead').
but console output follow error message:
Uncaught SyntaxError: Illegal break statement
break is to break out of a loop like for, while, switch etc which you don't have here, you need to use return to break the execution flow of the current function and return to the caller. See similar post here: illegal use of break statement; javascript
Tank.tanks.forEach(function(tank, i, arr) {
if(tank.id == 0) {
tank0Dead = false;
return;
};
});
if(tank0Dead == true) {
alert('tank with id 0 is dead');
};
jsfiddle : https://jsfiddle.net/oqc5Lw73/6/
You can't quit from forEach using break. Just remove break, and it will work.
P.S: honestly, it is better to refactor that code:)
Your only problem is that you can't use the break; statement in a forEach function.
But you can in a for() loop, so here is the equivalent code with a for :
for (var i = 0; i < Tank.tanks.length; i++){
if (Tank.tanks[i].id == 0){
tank0Dead = false;
break;
}
}
https://jsfiddle.net/oqc5Lw73/5/
But I agree with #dimko1 about the idea of refactoring the code
You can not break a forEach callback, simply because it's a function.
Here's updated working jSfiddle
If you really want to break it, you can use exception like code below.
try {
[1,2,3].forEach(function () {
if(conditionMet) {
throw Error("breaking forEach");
}
});
} catch(e) {
}
Otherwise you can use jQuery's each() method. when it's callback returns false it stops.
jQuery.each([1,2,3], function () {
if(conditionMet) {
return false;
}
});

Categories

Resources