Transform my if conditional to switch case with regex option: javascript - javascript

I would like to transfer my if condition to switch case, because then it would look nicer in my code. (I have several switch case).
I can't set the switch parameter to true, because this will break the logic of my code.
if (/(.*)_ERROR/.test(action.type)) {
alert('ok'); //working
}
switch (action.type) {
case /(.*)_ERROR/:
alert('ok'); //not working
break;
...
}
How to write it? The idea is to enter the case only if the word "error" is in the string

Not very ideal but you can use named groups:
const reg = /(?<warning>(.*)_WARNING)|(?<error>(.*)_ERROR)|(?<info>(.*)_INFO)/; // warning, error, or info.
const match = action.type.match(reg);
if (match) {
const groupName = Object.keys(match.groups).find(group => match.groups[group] !== null);
switch (groupName) {
case 'error': // like TEST_ERROR
case 'warning': // like TEST_WARNING
case 'info': // like TEST_INFO
default:
}
}

Related

javascript retrieve value from a map

I am trying to develop a google script app.
Here is one function to create an array map.
function getOffices(){
var result=AdminDirectory.Groups.list({domain:"example.com"})
result=result.groups.filter(function(group){
var str=group.email;
return str.search("-office#example.com")>=0;
})
result=result.map(function(group){ return {name:group.name,email:group.email}})
return result;
}
I have created a logic piece, that I want to execute certain actions based on the results, that looks like this:
var getOrgUnitPath = (accountOffice, accountType) => {
if (accountType === 'facilitator') {
return 'Limited Accounts/Gmail Plus Calendar';
} else {
switch (accountOffice) {
case accountOffice.includes('Boston'):
return "/Standard-Access/Boston";
break;
case accountOffice.includes('New York'):
return '/Standard-Access/New York';
break;
case accountOffice.includes('Lincoln'):
return '/Standard-Access/Lincoln';
break;
default:
return '/Standard-Access';
break;
}
}
};
Lastly, I try to set the organizational unit -- which is ultimately what i am trying to do, but can't seem to get the syntax right, I have tried everything I can think of. I have hardcoded the "accountType" and it worked, so I know the formObject.accountType is functioning properly.
orgUnitPath: getOrgUnitPath(accountType, formObject.accountType),
Thanks in advance!
This is a wrong usage of switch case.
if accountOffice's would be just New York, Boston, Lincoln. Remove the complex condition and replace with
switch (accountOffice) {
case "Boston":
return "/Standard-Access/Boston";
break;
case "New York":
return "/Standard-Access/New York";
break;
case "Lincoln":
return "/Standard-Access/Lincoln";
break;
default:
return "/Standard-Access";
break;
}
If not, use if-else if you have complex condition to check rather than simple match cases
if (accountOffice.includes("Boston")) {
return "/Standard-Access/Boston";
} else if (accountOffice.includes("New York")) {
return "/Standard-Access/New York";
} else if (accountOffice.includes("Lincoln")) {
return "/Standard-Access/Lincoln";
} else {
return "/Standard-Access";
}
I rewrote the code so I could get a better understanding of it. From what I can tell, getOffices lists all offices and getOrgUnitPath returns a path including the first office that matches the ordered list of offices ['Boston', 'NY', 'Lincoln']. If that's the case, what's missing is that the first argument to getOrgUnitPath should be getOffices(), right? (Notice it is the execution of the function getOffices.)
Here's the code "simplified" to my liking. I hope it helps:
const getOffices = () => {
const bigList = x.y.list({ domain: 'example.com' }) // ?
return bigList
.filter(cur => ~cur.email.search('abc'))
.map(cur => ({
name: cur.name,
email: cur.email
}))
}
const getPath = (accOffice, accType) => {
if (accType === 'xyz')
return 'foobar'
const city = ['Boston', 'NY', 'Lincoln']
.find(cur => accOffice.includes(cur))
return `yadayada/${city}`
}
const theFinalObj = {
orgUnitPath: getPath(getOffices(), 'rightHardcodedType')
}

How to match a template string in switch statement with js?

I have a function that returns a component that depends on the pathname of the window.
getComponentByPathname = (pathname) => {
switch(patname){
case "/view1": return <ViewOneComponent>;
case "/view2": return <ViewTwoComponent>;
}
But the problem starts when I try to evaluate a template string that has one id
getComponentByPathname = (pathname) => {
switch(pathname){
case "/view1": return <ViewOneComponent>;
case "/view2": return <ViewTwoComponent>;
case `/view3/${getId()}`: return <ViewThreeComponent>;
}
It's only working with the first two cases. Why?
Also, I make another attempt. In this case, I literally paste the string with the Id in the third case, like this:
case "view3/1234567": return <ViewThreeComponent>;
And works. But the problem is that I can not hardcode the id in the string.
How I can evaluate that?
My guess would be that getId() is returning a different value then what you expect. I would try the following and make that getId() is returning the expected value when it is being calculated
getComponentByPathname = pathname => {
const case3 = `/view3/${getId()}`;
console.log(`case3 = ${case3}`);
console.log(`pathname = ${pathname}`);
switch (pathname) {
case '/view1':
return <ViewOneComponent>;
case '/view2':
return <ViewTwoComponent>;
case case3:
return <ViewThreeComponent>;
}
};
But if you only need to decide which component to render based on your path then something like this might be more appropriate
const examplePaths = ['view1/', 'view2/', 'view3/', 'view3/1241232', 'view3/8721873216', 'view4/', 'vi/ew1', ''];
const mapper = {
view1: 'ViewOneComponent',
view2: 'ViewTwoComponent',
view3: 'ViewThreeComponent'
};
examplePaths.forEach(ent => {
const splitPaths = ent.split('/');
const mapped = mapper[splitPaths[0]];
if (mapped) {
console.log(mapped);
} else {
console.log('Path not supported');
}
});
Works fine here
function getId() {
return 1234567
}
function test(pathname) {
switch (pathname) {
case '/view1':
return 'ViewOneComponent'
case '/view2':
return 'ViewTwoComponent'
case `/view3/${getId()}`:
return 'ViewThreeComponent'
default:
return 'fail'
}
}
console.log(test('/view3/1234567'))

Ajax and JSON arrays

I'm trying to use JSON data format together with jQuery and, well, it would be surprising if it worked.
In my remoteServiceEngine.php, I have something like this:
$jResponse[0] = json_encode(array("jAction" => "add", "jObject" => "listCountries", "jBody" => "test"));
$json_data = json_encode(array("jRequestState" => $jRequestState, "jMessage" => $jMessage, "jResponse" => $jResponse));
echo $json_data;
And this is how it is handled in JS:
success: function(remoteResponse){
switch(remoteResponse.jRequestState) {
case 0:
$("#removeServiceMessage").fadeIn(2000).html('<div class="remoteError">'+remoteResponse.jMessage+'</div>').fadeOut(2000);
break;
case 1:
$("#removeServiceMessage").fadeIn(2000).html('<div class="remoteSuccess"><B>Success:</B> '+remoteResponse.jMessage+'</div>').fadeOut(2000);
for (i = 0; i < remoteResponse.jResponse.length; i++) {
switch(remoteResponse.jResponse[i].jAction) {
case "add":
$("#"+remoteResponse.jResponse[i].jObject).fadeIn(1000).append(remoteResponse.jResponse[i].jBody);
break;
case "remove":
$("#"+remoteResponse.jResponse[i].jObject).fadeOut(1000);
break;
case "update":
$("#"+remoteResponse.jResponse[i].jObject).fadeIn(1000).html(remoteResponse.jResponse[i].jBody);
break;
default:
alert(remoteResponse.jResponse[i]);
break;
}
}
break;
}
}
The whole problem is that I cannot access successful content. With $jRequestState = 1 and the forementioned $jResponse[0], switch goes directly onto default and this is the output I get:
{"jAction":"add","jObject":"listCountries","jBody":"test"}
but I cannot figure out how to access these elements. I tried it with:
alert(remoteResponse.jResponse[i]['jAction']);
and
alert(remoteResponse.jResponse[i][0]); //yeah, that's kinda stupid solution, but well...
Since I've never used JSON with jQuery, I can't figure out how to deal with that. Help, anybody?
Like adeneo said in the comment you jsonencode twice. Your php code should look like:
$jResponse[0] = array("jAction" => "add", "jObject" => "listCountries", "jBody" => "test");
$json_data = json_encode(array("jRequestState" => $jRequestState, "jMessage" => $jMessage, "jResponse" => $jResponse));
echo $json_data;

Can I implement/put an array on a switch conditional?

I was building my code when came to my mind a bizarre idea, can I implement/put an array inside a switch?
I mean, how can I make the codeHide case work? with this piece of code it don't work.
When I ask to set the command and I put hide() (that is codeHide[0] on the codeHide array) I want to switch take the codeHide case (my if-statement) and return an alert telling me the alertMessage of that particular array element.
If I put hide(background) (that is codeHide[1] on the codeHide array) I want to switch take the codeHide case else (of my if-statement) and return an alert telling me the alertMessage of that particular array element(in the is-statement).
Hope you understand me.
Doing this it don't work and I think it's because the "case codeHide:".
And this is what I've done so far:
var codeHide = ['hide()', 'hide(background)'];
$(".code").on("click", function () {
var codePrompt = prompt("Set the code in the command line."),
alertMessage = "",
consoleMessage = "Used '" + codePrompt + "' command.";
switch (codePrompt) {
case codeHide:
if (codeHide[0]) {
alertMessage = "Hiding elements...";
} else {
alertMessage = "Hiding Background...";
}
break;
default:
alertMessage = consoleMessage = "We are sorry but you entered a WRONG command, try again tho!\ntyped: " + codePrompt;
break;
}
alert(alertMessage);
console.log(consoleMessage);
});
I think you are trying something like
var commands = {
hide: 'hide()',
hideBg: 'hide(background)'
};
var codePrompt = prompt("Set the code in the command line."),
alertMessage;
switch (codePrompt) {
case commands.hide:
alertMessage = "Hiding elements...";
break;
case commands.hideBg:
alertMessage = "Hiding Background...";
break;
default:
alertMessage = "WRONG command";
break;
}
}
However, you can also use
var commands = {
'hide()': "Hiding elements...",
'hide(background)': "Hiding Background..."
};
var codePrompt = prompt("Set the code in the command line.");
var alertMessage = commands[codePrompt] || "WRONG command";
I guess you also want to run some functions:
var commands = {
'hide()': {
text: "Hiding elements...",
funcion: someFunctionToHide
},
'hide(background)': {
text: "Hiding Background...",
funcion: someFunctionToHideBackground
}
};
var codePrompt = prompt("Set the code in the command line."),
command = commands[codePrompt];
if(!command) {
alertMessage = "WRONG command";
} else {
alertMessage = command.text;
command.function();
}
switch operates by comparing the value being switched on to each of the possible cases using the identity operator ===. This means that you can put an array inside a case, and it will work as specified (but certainly not very intuitively for arrays):
var x = [1];
var a = [1];
switch (x) {
case [1]: alert("it's [1]!"); break;
case a: alert("it's a!"); break;
case x: alert("it's x!"); break;
}
This will alert "it's x!", while you might be expecting that either of the preceding two cases would be "good enough" to trigger. But that's just how === works:
[1] === x // false
a === x // true
x === x // true
So while you can technically use an array, in practice it would be very unusual to have a situation where it's actually useful to do so.
Going back to your code, since the values you are interested in are strings it seems that using a simple object as a map would do just fine:
var commands = {
"hide()": {
alert: "Hiding elements...",
console: "Blah blah"
}.
"hide(background)": {
alert: "Hiding background...",
console: "Blah blah"
}.
};
var fallback = {
alert: "Sorry, wrong command",
console: "Sorry, wrong command"
};
which would then allow you to write
var result = commands[input] || fallback;
alert(result.alert);
console.log(result.console);

Using switch statement to evaluate regex in javascript

I'm trying to manage my if statements into a switch statement to evaluate regex, but I don't know how I can go about it. I tried many possibilities but cannot do it. See code below, is it right?:
var username = $('input.username'),
phone = $('input.phone'),
numRegex = /^[0-9]/i,
alphaRegex = /^[a-zA-Z]/i,
usernameVal = username.val(),
phoneVal = phone.val();
switch (phoneVal) {
case numRegex.test(phoneVal):
console.log('Only digits please.');
break;
default:
console.log('It\'s all good.');
}
Many thanks.
I think this kind of defeats the point of the switch statement having the conditions in the case statements. It's intent is to test multiple outputs given a single input.
Perhaps if JavaScript supported multiple inputs (or destructuring of arrays) in a switch..case I could see something like this:
switch (numRegex.test(phoneVal), alphaRegex.test(usernameVal)) {
case false, false:
console.log('Neither are valid.');
break;
case true, false:
console.log('Invalid username.');
break;
/* snip */
default:
console.log('All\'s good.');
}
But alas, I'd say sticking with if..else is a better and easier to follow/understand option, in this case:
if (numRegex.test(phoneVal)) {
console.log('Only digits please.');
return false;
} else if (alphaRegex.test(usernameVal)) {
console.log('Only alpha-numeric please.');
return false;
} else {
console.log('It\'s all good.');
return true;
}
If you are only using each regex once why not just refactor this into a block of ternaries?
Maybe something like this:
/^\S/.test($('#name').val()) !== true
? invalidEls.push('name:invalid')
: invalidEls.push('name:valid');
$('#phone').val().match(/^(1-?)?([2-9]\d{2}|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/)
? invalidEls.push('phone:valid')
: invalidEls.push('phone:invalid');
$('#email').val().match(/[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9]){1,}?/)
? invalidEls.push('email:valid')
: invalidEls.push('email:invalid');
Another similar pattern;
try {
if (!alphaRegex.test(usernameVal))
throw ('Only letters please.');
if (!numRegex.test(phoneVal))
throw ('Only digits please.');
...
return true;
} catch (e) {
console.log(e);
}

Categories

Resources