Switch statement not behaving like it should - javascript

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

Related

Javascript switch case that runs code when any case is true?

I have a standard switch case block:
switch(variable) {
case "option1":
alert("Option 1");
break;
case "option2":
alert("Option 2");
break;
}
And I would like to run this code:
alert("Any Option");
Is there a simple way to run this code when either of the cases match, without adding the code to every case, and without rechecking "variable" (i.e. not using an if statement after the switch)?
There are a bunch of really hacky ways to do what you are suggesting (named do loops with break/continue, recursive functions with switch statements, etc.) but the cleanest would be to use a function, like so:
var variable = "option1";
function checkValue (val) {
switch (variable) {
case "option1":
alert("Option 1");
return true;
case "option2":
alert("Option 2");
return true;
default:
return false;
}
}
if (checkValue(variable)) {
// run common code
alert("Any option");
}
A labeled block allows you to break out of it at any time. If you break in the default case, you can run some code following the switch statement when either of the cases match and without rechecking the variable, as requested:
let variable = prompt("option1 or option2?");
select: {
switch(variable) {
case "option1":
alert("Option 1");
break;
case "option2":
alert("Option 2");
break;
default:
break select;
}
alert("Both Options");
}
However, I don't recommend this! Labels make the code execution path less clear. Above code is not readable. Rechecking the variable is a better approach.
Not directly with a switch statement. See The Switch Statement, ECMAScript 2016 standard.
In particular:
Runtime Semantics: Switch Evaluation
Runtime Semantics: CaseBlockExpression
The language spec does not contain the feature that you are looking for.
Why not making a function called by both cases?
switch(variable) {
case "option1":
dualAlert("Option 1");
break;
case "option2":
dualAlert("Option 2");
break;
}
function dualAlert(text){
alert(text);
alert('Common Alert');
}
I don't think i would ever use the pattern you described, nonetheless something like this could suit your needs.
/**
* Use this method to simulate a "finally" statement in a
* method that resembles a switch
*
* #param {*} value - The value to compare
* #param {Array<*, boolean, function>} options - The collection of switch statements
* First value is the value to compare against the original value
* Second value specifies if this statement should behave like a break at its end
* Third value is the action to take when the value matches
* #param {function} finallyFn - The method which is run if any statement was executed
*/
function switchWithFinally(value, options, finallyFn) {
var matched = false,
breakSwitch = true;
for(var i = 0; i < options.length; i++) {
if(!breakSwitch || value === options[i][0]) {
options[i][2]();
matched = true;
breakSwitch = options[i][1];
}
}
if(matched) finallyFn();
}
/**
* Example call, should return
* Option 2
* Option 3
* Any option
*/
switchWithFinally(
'option2',
[
['option1', true, function() {
console.log('Option 1');
}],
['option2', false, function() {
console.log('Option 2');
}],
['option3', true, function() {
console.log('Option 3');
}]
],
function() {
console.log('Any option');
}
);

Switch Statement and jQuery hasClass function

I am trying to use a switch statement to check if the current page has a specific body class. This is kind of what I am looking for:
var bodyClass = $('body').hasClass('className')
switch(bodyClass) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
I do understand that the jQuery hasClass function returns true of false and is used like $('body').hasClass('someClassName') and this will return true or false. Also, my body typically has about 7-10 different class names for a given page.
This is not the use case for a switch in my opinion, but a simple set of branches
var body = $('body');
if(body.hasClass('abc')) {
}
else if(body.hasClass('def')) {
}
else {
/* default case */
}
/* etc */
I agree with the other answer that you're better suited to just use if, else if statements here, but an alternative would be to rip the classes off the body tag and check them against your strings:
var bodyClasses = ($('body').attr('class') || '').split(' ');
for (var i = 0, len = bodyClasses.length; i < len; i++) {
switch(bodyClasses[i]) {
case 'homepage':
// console.log("This is the homepage");
break;
case 'residential-page':
// console.log("This is the residential page");
break;
default:
// console.log("default code block ran");
}
}
I know this is an old thread, but it may help someone else.
If you are able to ensure the classes for the element are declared in a specific order, you could ensure the class you are checking for is first / last in the list, and use something similar to this:
var bodyClass = $('body').attr('class');
var firstClass = bodyClass.slice(0, bodyClass.indexOf(' '));
switch(firstClass) {
case 'homepage':
// Some code here
break;
case 'residential-page':
// Other code here
break;
default:
// More code here
}

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"

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

javascript switch(true)

Hi i am trying to handle an ajax json response
here is my code
success: function (j) {
switch(true)
{
case (j.choice1):
alert("choice2");
break;
case (j.choice2):
alert("choice2");
break;
default:
alert("default");
break;
}
}
based on what j is return i do my action BUT i keep getting the default.
I have alert the j values and come correct.Some how case (j.choice1) case (j.choice2) is not working.
I tried case (j.choice1!="") (j.choice2!="") But in this scenario i keep getting the first choice.
What am i missing
It works for me:
var a = 0, b = true;
switch(true) {
case a:
console.log('a');
break;
case b:
console.log('b');
break;
}
However, the case labels must be equal to true, not just implicitly true.
Also, only the first case that evaluates to true will execute.
SOLVED
Based on SLaks answer i modify the code as below
if(j.choice1){ var choice1=true;} else { var choice1=false;}
if(j.choice2){ var choice2=true;} else { var choice2=false;}
switch(true)
{
case choice1:
alert("choice1");
break;
case choice2:
alert("choice2");
break;
default:
alert("default");
break;
}
For all asking why switch and not if.
Switch will execute only 1 statement, but if can execute more than 1 if any mistake come form response (for example if set choice1 and choice 2 the if will alert both but switch will alert only choice1).
The response expecting as choice has to do with credit card charge to bank so i want to ensure that only 1 action will exetute
Thank to all
You need to read up on the switch statement. You should not be switching on a constant value.
It appears that you need to use if statements, as you don't really want to be switching on your j value:
success: function (j) {
if (j.choice1)
{
alert("choice1");
break;
}
if (j.choice2)
{
alert("choice2");
break;
}
alert("default");
}
}
In a case like this, a better way to do this is probably something like:
success: function (j) {
if(j.choice1 || j.choice2) {
alert("choice2");
} else {
alert("default");
}
}
Why not use an object literal instead of a switch(true) ?
const j= {
choice1: false,
choice2: true
};
const map = {
true: 'default',
...(j.choice1 ? {[`${j.choice1}`]: 'choice1'} :{}),
...(j.choice2 ? {[`${j.choice2}`]: 'choice2'} :{})
}['true']
console.log(map) // 'choice2'

Categories

Resources