Javascript - evaluating parameter again - javascript

I would like to create a function "when", that will work as a normal command, or just a function, and will be able to re-evaluate its parameters.
for example:
when(k==0) {
do something;
}
or
when(k==0, function() {
do something;
});
The thing is, that k is now for example equal to 1, and this function needs to always re-evaluate k==0 to determinate if it changed to 0.
*I do not want to send k==0 as a string 'k==0'.
Is that possible? If so, how?
*This is an academic question, please don't explain why it is so very wrong to create this function.

something like this?
function when(condition, callback){ if (condition) callback() }
and call it like
var a = 0;
when(a == 0, function(){ console.log( "yeyyyy") } );
after reading the comments above
some kind of mechanism for observing when a variable's value changes
change when method to
function when(lhs, operator, rhs, callback)
{
var result = false;
switch( operator )
{
case "==": result = (lhs==rhs); break;
case "===": result = (lhs===rhs); break;
case "<": result = (lhs<rhs); break;
case ">": result = (lhs>rhs); break;
case "<=": result = (lhs<=rhs); break;
case ">=": result = (lhs>=rhs); break;
default: result = true;
}
if (result) { callback() }
else { setTimeout( function(){ when(lhs, operator, rhs, callback) }, 1000 ); }
}

What would work would be to use a lambda for both the condition and the action. Using arrow function expressions (thanks #Kyll), it's even reasonably compact.
when (() => k == 0, () => { do something; });

Related

Switch statement not behaving like it should

so i have a piece of code where i have an array (ar=[1,2,3,4,5]) and two functions. the functions are supposed to do the exact same thing: print out something if 1 exists in the array. but function func is always returning "nope" instead of "one" but function another always return the right thing. the only difference between the two functions is function func have a switch instead of an if/else. why? in the source code there are about 12 cases so i actually need to use the switch.
var ar=[1,2,3,4,5];
function func(num){
var one=num;
switch (one) {
case one===1:
console.log("one");
break;
default:
console.log("nope");
break;
}
}
function another (num) {
if(num===2){
console.log("found two");
} else if(num===3){
console.log("found thre");
} else{
console.log("nope");
}
}
ar.forEach(func);
ar.forEach(another);
You have to use the value you want to compare to one
hence
case 1:
instead of
case one===1
here's a fiddle
https://jsfiddle.net/cunx1ono/
Easiest way. Change the switch param to true if you want to use a comparison in the case, because one===1 returns true/false. This is why you always get "nope".
var ar=[1,2,3,4,5];
function func(num){
var one=num;
switch (true) {
case one===1:
console.log("one");
break;
default:
console.log("nope");
break;
}
}

capturing function call as a string

using JS; I am passing a function name as an optional argument. I would like to make a switch case that reads the functions name that is being passed. How would I capture the functionVariable as if it were a string "functionVariable"?
Example:
function test(functionVariable)
{
switch(functionVariable)
{
case firstFunction:
alert('1st');
break;
case secondFunction:
alert('2nd');
break;
}
}
When I alert functionVariable, it prints the whole function. It makes sense why but I'm trying to work around it and just get the functions name.
EDIT
Working example
function test(functionVariable)
{
switch(functionVariable.name)
{
case firstFunction:
alert('1st');
break;
case secondFunction:
alert('2nd');
break;
}
}
You could use Function.name.
function doSomething() {
// does something
}
console.log(doSomething.name); // "doSomething"
Note that this only works for function declarations and named function expressions. Unnamed function expressions won't work.
var getA = function getA() {
};
console.log(getA.name); // "getA"
var getB = function() { // Notice the lack of a name
};
console.log(getB.name); // ""
You can use functionVariable.name, here is an example:
x = function test() {}
console.log(x.name)
// logs "test"

JavaScript alternatives to handling switch cases that have properties

I have HTML elements defined like this
<div id="Jacob" validation="required alpha-numeric"></div>
<div id="Peter" validation="required minlen:4 maxlen:20"></div>
And in Javascript I was parsing and handling the validation="property1 property2 ... propertyN" like this:
// called from a foreach that uses split(' ')
validate(type) {
switch(type) {
case "required":
// ...
break;
case "alpha-numeric":
// ...
break;
}
}
I realise using a switch like this might be a bit verbose and archaic.
What would be an elegant way to parse parameters that have their own properties/values?
I don't know where you got the impression that switch statements are archaic. They're not.
As far as your particular case, you can use .split(":") to split the individual parts apart, and then match on that:
function validate(type) {
var parts = (type || "").split(":");
switch(parts[0].toLowerCase()) {
case "required":
// ...
break;
case "alpha-numeric":
// ...
break;
case "minlen":
// validate against parts[1]
break;
}
}
If you wanted to use a lookup rather than a switch, you can do that, but I'd say that's just a matter of preference:
var validators = {
"required": function (value) {
},
"alpha-numeric": function (value) {
},
"minlen": function (value, len) {
}
};
function validate (value, type) {
var parts = (type || "").split(":");
var validator = validators[parts[0].toLowerCase()];
if (validator) {
var result = validator(value, parts[1]);
}
}
One potential benefit of the second approach is that new validators can be added to the validator object at runtime, though if you wanted to make a pluggable system, you'd probably want to go with something more robust than just a plain object that can be arbitrarily modified.
you can create json of key function pair. And pick function using your type and call it.
var objOfFunction = {};
objOfFunction["required"] = requiredFunction;
objOfFunction["alpha-numeric"] = alphanFunction;
function validate(type) {
objOfFunction[type]();
}
function requiredFunction(){
alert("required");
}
function alphanFunction(){
alert("in alpha");
}
validate("required");
validate("alpha-numeric");

add a wildcard to a JavaScript switch statement

is there a way i can create a switch statement with a wildcard with the logic of:
case: '/jobs/'+WILDCARD and ending in +'-jobs' :
this is for the window.location.pathname, which could be '/jobs/design-jobs', or '/jobs/engineer-jobs' etc
but, there are other pages which start with '/jobs' I don't want this to apply to, e.g '/jobs/post'
or any suggestions on a better way?
No there are not wildcards for switch statements, but you could e.g. use RegExp and test against it:
if( path.match(/^\/jobs\/(.*)-jobs$/) !== null ) {
//jobs url
} else {
switch( path ) {
case '/jobs/post':
//something else
break;
}
}
One trick you can use in some cases could be to use a function to normalize the input of your switch, to turn variable inputs into the specific cases:
Instead of:
switch(input) {
case 'something': // something
case 'otherthing': // another
case '/jobs/'+WILDCARD: // special
}
You could do:
function transformInput (input) {
if (input.match(/jobs.*-jobs/) return 'JOBS';
return input;
}
switch(transformInput(input)) {
case 'something': // something
case 'otherthing': // another
case 'JOBS': // special
}
You can do something like this:
var categories = {
design: function(){ console.log('design'); },
engineer: function(){ console.log('engineer'); }
};
for(var category in categories)
if(window.location.pathname === '/jobs/' + category + '-jobs')
categories[category]();

Implementing eachChild for a specefic case

I have a few places in my code that are very similar to this snippet:
tag_iter = hold_tags_el.firstChild;
do {
if (tag_iter === null) {
hold_tags_el.appendChild(paragraph_el);
break;
}
if (par_el.innerHTML < tag_iter.innerHTML) {
hold_tags_el.insertBefore(paragraph_el, tag_iter);
break;
}
if (tag_iter === hold_tags_el.lastChild) {
NS.insertAfter(tag_iter, paragraph_el);
break;
}
tag_iter = tag_iter.nextSibling;
} while (tag_iter !== null);
This can be abstracted to:
tag_iter = ref_el.firstChild;
do {
// loop logic
tag_iter = tag_iter.nextSibling;
} while (tag_iter !== null);
In a function form this would look like:
The Call:
eachChild(par_el, function (tag_iter, par_el) {
// loop logic
});
The Definition:
NS.eachChild = function (par_el, func, context) {
var iter_el = par_el.firstChild,
result;
do {
result = func.call(context, iter_el, par_el);
if (result) {
break;
}
iter_el = iter_el.nextSibling;
} while (iter_el !== null);
}
Is there a library that implements this pattern / idiom?
What improvements can be made to eachChild?
Are there any errors in eachChild?
Applying the idiom we have:
Snippet A
NS.eachChild(el, function(tag_iter, par_el){
// first
if (tag_iter === null) {
par_el.appendChild(paragraph_el);
return true;
}
// middle
if (par_el.innerHTML < tag_iter.innerHTML) {
par_el.insertBefore(paragraph_el, tag_iter);
return true;
}
// last
if (tag_iter === hold_tags_el.lastChild) {
par_el.appendChild(paragraph_el);
return true;
}
});
What improvements can be made?
Many. Your snippet with its do-while loop and the many breaks is overly complicated and hard to understand. It can be simplified to
var tag_iter = hold_tags_el.firstChild,
search = par_el.innerHTML;
while (tag_iter !== null && search >= tag_iter.innerHTML)
tag_iter = tag_iter.nextSibling;
hold_tags_el.insertBefore(paragraph_el, tag_iter);
Notice that insertBefore with null as second argument, insertAfter(lastChild) and appendChild do exactly the same thing.
With that simplification, you don't need that eachChild function any more. But maybe a little different one:
NS.findChild = function(parent, condition) {
var child = parent.firstChild;
for (var i=0; child!==null && condition(child, i); i++)
child = child.nextSibling;
return child;
};
// then simply:
var el = NS.findChild(hold_tags_el, function(tag_iter) {
return tag_iter.innerHTML < par_el.innerHTML;
});
hold_tags_el.insertBefore(paragraph_el, el);
Is there a library that implements this pattern / idiom?
I don't know any. But there are many libs with generic iterator methods (some of them with break functionality) that can easily be applied on childNodes collections.
Are there any errors in eachChild?
It calls the callback even when there is no firstChild (with null as argument). That's at least unconventional, if not wrong - not what you would expect from an iteration. If you think to need it, this should better be made a separate case (a separate callback); otherwise it requires an extra condition in the callback. However in the given usecase you do not need it, as that is a search - see the findChild function above - where eachChild is inappropriate.
What improvements can be made to eachChild?
Additionally to parEl maybe a counter argument might be nice - check the signature of the standard forEach Array method.

Categories

Resources