Javascript Switch statement not working as expected with string - javascript

I'm trying to use the following switch statement in an ajax success callback:
success: function(datain) {
switch (datain)
{
case "ERROR. No ID. Try again":
$(".errors").append('There was an error.');
break;
case "ERROR. Wrong captcha. Try again":
$(".errors").append('There was an error.');
break;
}
}
datain is a string (typeof datain returns string) and it does indeed contain the same text, capitalization and punctuation as the case so why would it not match either of the cases?
console.log(datain) and console.log("ERROR. No ID. Try again") match exactly and both return a typeof of string so why does my case never get matched?
Solution and cause
The solution is offered by palswim below $.trim(datain). The cause was visible in Firebug and it was the fact that the string had a newline at the end while my switch case did not... so I was getting "foo\n" and trying to match "foo". Given that js uses === in the switch this, naturally (now that I see it), is why it failed.

Try trimming your strings.
In jQuery:
switch($.trim(datain))
{ //...
But trying to match strings that long is fraught with peril!

No clue as to why neither are called based on what you say. At the risk of suggesting the obvious though: Put in a "default" statement at the end of the switch to make sure you're function is being called, and in the default statement do some if comparisons: datain === "ERROR:...".
One other thing that might be easy to miss is if (possibly) there should be a "." at the end of "...Try again."

You can also do this:
success: function(datain) {
switch (datain)
{
case `"ERROR. No ID. Try again"`:
$(".errors").append('There was an error.');
break;
case `"ERROR. Wrong captcha. Try again"`:
$(".errors").append('There was an error.');
break;
}
}
A character before " is `. It is right before 1 on my keyboard.

Related

How to filter by not exact text JS

Here is a part of ag-grid JS code that filter cells with exactly text:
function doesExternalFilterPass(node) {
switch (status) {
case 'released':
return node.data.Status == 'Released';
case 'early-access':
return node.data.Status == 'Early access';
case 'in-development':
return node.data.Status == 'In development';
case 'rtt-strategy':
return node.data.Genre == /.'RTT'./;
default:
return true;
}
}
For example, one of the strings filter all cells containing Released in Status column, other containing RTT in Genre column. But I need that strings like RTT, RTS, Action also to be filtered. As I understand, I should use regular expressions, I try this
return node.data.Genre == /.'RTT'./;
but it doesn't work.
Any ideas to get many-words filtering?
You don't need regex for this. Regex should be avoided, if possible. If I understand it correctly, you want to check if a string contains a substring. For that you can use String.prototype.includes() method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes
Example code:
case 'rtt-strategy':
return node.data.Genre.includes('RTT');
If you still want to use regex, then you can use the RegExp.prototype.test() method: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test. First of all, you really should look up how to use regex in js, because your example code is way off. Secondly, example code:
/RTT/.test(node.data.Genre)
Or if you want case insensitive, then:
/RTT/i.test(node.data.Genre)

Javascript Case: "look at" + item

Okay, so this may be a repeat, but I personally haven't seen anything on the internet or in Stackoverflow about this.
I am working on a game project and I have been trying to make a text-based game.
In this game, I have a switch statement, for when the user enters a command.
So far I have things for Inventory and Look (Look around the environment), but how do I work with specific things in a switch statement?
For example:
submit = function(input) {
switch(input) {
case "LOOK":
lookaround();
break;
case "LOOK AT" + item:
look();
}
}
It is the LOOK AT line I am having issues with. I do not know how I can make a string work in that format, unless I had a case for every single item individually, example case "LOOK AT ORANGE" or case "LOOK AT TREE".
I hope I am explaining this thoroughly enough. Can anyone give me some advice?
Thanks
EDIT
I think it is important to note that the user is typing the input into an input box, so the value of the input is going to be a string.
If it will help to see the code I have made, please let me know in the comments below.
EDIT
THANKS FOR YOU HELP GUYS!
I used a regular expression (Thanks #red-devil) and a mixture of slicing. It works perfectly now!
Switch works with constants, not expressions like 'LOOK AT' + anything.
You could define an object for map any of your cases to your own functions. Like that:
var looks = {
'lookat-something' : function() {
alert('something');
},
'lookat-other-thing' : function() {
alert('other thing');
},
};
var x = 'lookat-other-thing';
looks[x]();
It much more flexible than using switch in any way.
If I understood you right, you want the user to be able to input LOOK AT and then any item name. The problem here is that you have this ominous item variable that could stand for anything and this is not going to work.
I would suggest one of these two ways:
Going along the lines of your example:
submit = function (input) {
switch (true) {
case input == "LOOK":
alert("Look")
break;
case input.startsWith("LOOK AT"):
alert(input)
break;
}
}
if (typeof String.prototype.startsWith != 'function') {
String.prototype.startsWith = function (str) {
return this.slice(0, str.length) == str;
};
}
And secondly, and this is the method I would recommend, you implement a way to parse any input into a command and parameters. A way to do this is to split the input at every space character and then the first value is the command and the rest would be the parameters. This would require you to use a one word command like LookAt and not LOOK AT.
So something like this:
function submit(input) {
var parts = input.split(" ");
var cmd = parts[0];
var args = parts.slice(1);
switch (cmd) {
case "Look":
lookAround();
break;
case "LookAt":
lookAt(args[0]);
break;
}
}

better way to write if else statement

First time writing Javascript. I just would like know if there is a shorter way of writing this:
<p id="demo"></p>
<script>
function myFunction() {
var letter = document.getElementById("myInput").value;
var text;
if (letter === "5544") {
text = "Abar, Marlon 1,800";
} else if (letter === "5545") {
text = "Pia, Darla 1,800";
} else if (letter === "5546") {
text = "Salazar, Alex 1,500";
//etc...
} else {
text = "Incorrect Account Number";
}
document.getElementById("demo").innerHTML = text;
}
</script>
Tried map but I couldn't get it to work.
There isn't really a shorter way to write an if statement in that way (which I will assume is what you're asking). However, there could be a few different ways to write this depending on how many things you want to check.
Use a Switch statement
There is a cleaner way when dealing with multiple cases that letter could be.
This would be a switch statement and it would look like this:
var text;
switch (letter) {
case "5544":
text = "Abar, Marlon 1,800";
break;
case "5545":
text = "Pia, Darla 1,800";
break;
// more cases
default:
text = "Incorrect Account Number";
break;
}
This reads a little better than an if else statement in some cases. The default keyword here acts as your else clause in an if else statement. The case acts as your different if statements if you will.
Essentially, the switch statement above will fall through each of the cases it defines until it finds a case that matches letter (such as "5544"). If none matches, it hits the default case. The break keyword at the end of each case stops things from falling through to the next defined case once a match is found.
This method could get cumbersome with more than 6 or 7 cases.
Create an object and look up the value
Now, a shorter way to get the value you want could be to define an object and get the value based on what has been entered like so:
var letter = document.getElementById('selector').value;
var obj = {
'5544': 'Abar, Marlon 1,800'
};
if (letter in obj) {
// do something if found
}
else {
// do something if not found
}
This could be an easy way to get a value if you have many values to check.
Other thoughts
As a side note to all of this, there are short hand if statements called ternary statements which you can find here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator ... However, I would not recommend nesting these as it becomes very complicated and not very readable.
Conclusion
So, to reiterate the answer to your question: No, there isn't really a shorter way to write an if else statement with many values. You can use a switch statement to make it cleaner. Use the object lookup method if you have many values you would like to check.
JavaScript has object (map) literals. Use them for terse code. In your final application you'll get the data for the map from someplace else and not code it directly into your website, but if you did, it would look like this:
document.getElementById( "demo" ).innerHTML = {
"5544" : "Abar, Marlon 1,800",
"5445" : "Pia, Darla 1,800",
...
}[ document.getElementById( "myInput" ).value ];
you can use switch for a long if - else -if ladder:
switch(expression) {
case n:
code block
break;
case n:
code block
break;
default:
default code block
}
This is how it works:
1)The switch expression is evaluated once.
2)The value of the expression is compared with the values of each case.
3)If there is a match, the associated block of code is executed.
if you need basic tutorials in java script then you should try w3 schools.

indexOf within Switch

I have a Javascript-based bot for a Xat chatroom which also acts as an AI. I've recently decided to redo the AI part of it due to it becoming an absolutely massive chain of else if statements, becoming nearly impossible to work with.
I did some research and came up with a new idea of how to handle responses. I'll give you the code segment first:
function msgSwitch(id,msgRes) {
var botResponse = [];
switch (msgRes) {
case (msgRes.indexOf("hi") !=-1):
botResponse.push("HELLO. ");
case (msgRes.indexOf("how are you") !=-1):
botResponse.push("I AM FINE. ")
case (msgRes.indexOf("do you like pie") !=-1):
botResponse.push("I CAN'T EAT. THANKS, ASSHAT. ")
default:
respond (botResponse);
spamCount(id);
break;
}
}
The idea here is to check msgRes (the user's input) and see how many cases it matches. Then for each match, it'll push the response into the botResponse array, then at the end, it'll reply with all the messages in that array.
Example
User Msg: Hi! How are you?
msgRes: hi how are you
Bot Matches:
hi > pushes HELLO. to array
how are you > pushes I AM FINE. to array
Bot Responds: HELLO. I AM FINE.
This in turn saves me the trouble of having to write an if for each possible combination.
However, after looking into it some more, I'm not sure if it's possible use indexOf inside of a switch. Does anyone know of a way around this or have a better idea for handling responses in the same manner?
EDIT:
To Avoid the XY Problem (To clarify my problem)
I need a clean alternative to using a massive chain of else if statements. There are going to be hundreds of word segments that the bot will respond to. Without the ability for it to keep searching for matches, I'd have to write a new else if for every combination.
I'm hoping for a way to have it scan through every statement for a match, then combine the response for each match together into a single string.
EDIT 2:
I should also add that this is being ran on Tampermonkey and not a website.
you just need to compare to true instead of msgRes (since cases use === comparison), and use break to prevent the annoying fall-though of the switch behavior:
function msgSwitch(id,msgRes) {
var botResponse = [];
switch (true) {
case (msgRes.indexOf("hi") !=-1):
botResponse.push("HELLO. "); break;
case (msgRes.indexOf("how are you") !=-1):
botResponse.push("I AM FINE. "); break;
case (msgRes.indexOf("do you like pie") !=-1):
botResponse.push("I CAN'T EAT. THANKS, ASSHAT. "); break;
default:
respond (botResponse);
spamCount(id);
break;
}
}
This is a perfectly valid logical forking pattern, known as an "overloaded switch". A lot of folks might not realize that each case: is an expression, not just a value, so you could even put an IIFE in there if needed...
My two cents for the gist of what you're trying to do:
function msgSwitch(id, msgRes) {
var seed = {'hi': 'HELLO. ', 'how are you': 'I AM FINE'};
var botResponse = [];
for (var key in seed) {
if (msgRes.indexOf(key) !== -1) {
botResponse.push(seed[key]);
}
}
}
In my opinion it is easier to change this program as you only have to edit the seed if you have more responses in the future. You can even stash the seed on some json file and read it (via ajax) so the program does not need to be changed if there are additional messages.

Javascript: Simple function, var not getting set

What am I doing wrong here? I even tried it with case instead of if and it does not work
function updateResultPage(the_resp,r) {
var to_alert="s";
if(the_resp=="11"){
to_alert="Thank you!!";
}
else if(the_resp=="22"){
to_alert="Error:.";
}
else if(the_resp=="33"){
to_alert="ERROR 234dfR,.";
}
alert("c "+to_alert+the_resp);
}
I get an alert that displays C s22
Why is it skipping past all the if() statements?
EDIT:
Ok, I added this code to see the exact value of resp: alert("d "+to_alert+" *"+the_resp+"*");
and the second * is coming on the next line, so it looks like i have a trimming problem...
Add
the_resp = the_resp.replace(/^\s*|\s*$/g,""); // will trim it.
at the beginning of your function.
Remove this
alert("c "+to_alert+the_resp);
or add an else
else{
alert("c "+to_alert+the_resp);
}
Might be worth checking to make sure you are passing in an actual string or string object (as opposed to say an int). May also be worth making sure there isn't any non-printing whitespace in your input by trimming appropriately..

Categories