How to Display something depending on variable given in angular - javascript

I need to show a word that is attributed to a number, in AngularJS.
Through the controller I send to the view a variable $game.complexity, and complexity can be a number from 1 to 4. I want to take that number and show it as a word:
1 ---> easy
2 --->medium
what I initially thought was that maybe it would work with a cutstom filter:
var filtersModule = angular.module("ttmatchApp.Filters", [])
filtersModule.filter("complexityFilter", function(){
return function(value){
switch(value)
{
case 1:
return "easy"
break;
case 2:
return "medium"
break;
case 3:
return "hard"
break;
case 4:
return "very hard"
break;
}
}
})
and call it like this:
<p>{{game.complexity | complexityFilter:game.complexity}} complexity</p></div>
i also tried it like this:
<p>{{game.complexity | complexityFilter}} complexity</p></div>
I define $scope.game within a controller, and i give it the necessary data through a json file. Other scope elements such as game.name work well, and show.
the filtersModule is also linked to the main module.
Do i have to introduce the filter to the controller as well?
Am i using the wrong method?

Once game.complexity is evaluated in the expression, it is outputted as a string. That means that your switch case should be on strings and not integers - "1" instead of 1, etc..
Edit: I was wrong, the expression is evaluated into a string, but the filter is still within that expression, so it receives game.complexity still as a number. The problem was what you solved in the comments.

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)

Cannot send email using switch statement

I'm using node mailer to send out the emails and have followed a youtube tutorial, but I did some changes. I want to the user to send an email to any of the 31 people the he/she will choose, and so we will call the number assigned to people being chosen is classNum.
When I assign an email to the to parameter, the code works, but if I remove it and use the switch statement, it give the 500 error.
const sendMail = (email, subject, text,classNum, cb) => {
const mailOptions = {
from: email,
subject,
text,
to: " "
};
switch(classNum) {
case 25:
mailOptions.to = 'thisIsAnEmail#gmail.com'
break;
}
This is probably the chunk of code that has a problem, please tell me if I need to add/post more code from the source code.
A switch expression uses strict equality
With the debugging info I asked for in the comments, you are passing in a string and you are comparing it against a number. So "25" === 25 is false.
You either need to make it a string
switch(classNum) {
case "25":
or convert classNum to a number
switch(Number(classNum)) {
case 25:
As #epascarello indicated, you have a string in classNum, not a number; as a result, you "case" doesn't match. You can fix this one of two ways:
Make sure classNum is a number, rather than a string (probably better, since classNum implies a number in the variable name) by using classNum = Number(classNum); OR
change your switch case to be a string: case '25':
I think option 1 is probably better, again because the variable name implies a number value.

Using if/else vs. switch

I'm wondering if it would be better to use a switch statement in my specific case.
I'm writing an Alexa Custom Skill, and I need to "redirect" to the appropriate intent depending on the available information (aka slots). Below is what I have currently (using if/else):
if (_type === "IntentRequest") {
this.handler.state = states.START;
if (_slots.indexOf("address") != -1) {
this.emitWithState("GoingToAddressIntent");
} else if (_slots.indexOf("place") != -1) {
this.emitWithState("GoingToPlaceIntent");
} else if (_slots.indexOf("type") != -1) {
this.emitWithState("GoingToTypeIntent");
} else if (_slots.indexOf("purpose") != -1) {
this.emitWithState("GoingToPurposeIntent");
} else {
this.emit("Unhandled");
}
}
I expect _slots to be an array of any permutations of the four elements, [ "address", "place", "type", "purpose" ]. Therefore, it could be anything from [ "address" ] to [ "place", "purpose" ] to etc. etc., but always in the same order (e.g. [ "purpose", "address" ] would never happen).
The order of the comparisons matters because there is a "hierarchy" of information; so if the "address" slot is present, I have to emit the "GoingToAddressIntent" regardless of what other slots are available. Given this requirement, I thought using a switch statement maybe more straightforward and readable despite having to have a few extra lines of code to "convert" the array of strings to an array of booleans. It clearly lays out the hierarchy & make sure they are evaluated in order. I could do:
if (_type === "IntentRequest") {
this.handler.state = states.START;
slots = [
_slots.indexOf("address") != -1,
_slots.indexOf("place") != -1,
_slots.indexOf("type") != -1,
_slots.indexOf("purpose") != -1
]
switch(slots.indexOf(true)) {
case 0:
this.emitWithState("GoingToAddressIntent");
break;
case 1:
this.emitWithState("GoingToAddressIntent");
break;
case 2:
this.emitWithState("GoingToTypeIntent");
break;
case 3:
this.emitWithState("GoingToPurposeIntent");
break;
default:
this.emit("Unhandled");
}
}
... in which case I have an extra line to define the array of booleans, use indexOf() to get the index of the first occurrence of a true literal (because all 4 slots are always in the order of hierarchy), and run it through the switch statement. However I wanted ask experts on their ideas of what best programming practice is in this case and the reasoning behind it because I want this to become a long-term project that is maintainable, and also I believe I can learn something from their insights.
Please leave a comment if you think this should be migrated to another community on SE, but from my research (although 3 years old) I believe this should be fine (I'm just not 100% confident on this).
If they're always in the order of precedence in _slots, maybe you could make a hash map to the state you're going to emit...
const map = {
address: "GoingToAddressIntent",
place: "GoingToPlaceIntent",
type: "GoingToTypeIntent",
purpose: "GoingToPurposeIntent"
};
const state = map[_slots[0]];
if (state) {
this.emitWithState(state);
} else {
this.emit("Unhandled");
}
I wouldn't go with your example of the switch statement. People could understand what you're attempting to do, but it does seem pretty convoluted. I use switch statements pretty liberally, mostly in backend code, and I think it could work fine here. A group of if/else is fine too, since there's only 4 cases you need to work through. Lets roll with the switch statement since that's what you're asking about.
Based on your explanation, the order is always going to be the same, although the first value you get may be different. So the solution would be to simply grab the first value, and switch over that.
if (!!slots.length) {
var keyword = slots[0];
switch (keyword) {
case 'address':
this.emitWithState("GoingToAddressIntent");
break;
case 'place':
this.emitWithState("GoingToPlaceIntent");
break;
case 'type':
this.emitWithState("GoingToTypeIntent");
break;
case 'purpose':
this.emitWithState("GoingToPurposeIntent");
break;
default:
this.emit('Unhandled'); // I typically throw an exception here
}
}

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.

Switch case in MustacheJs

Using Mustache js (a logic less templating) is there a way i can achieve switch case? this i need because a class is assigned to dom element based on the value for example:
switch(tasks.Count)
{
case 0:
element.Class = "no-tasks";
break;
case 1:
element.Class = "one-tasks";
break;
.
.
.
}
that's the code i got now, how do i transform it to template( I Believe having methods on model being rendered is the one option) But adding methods to determine which class to use is an overkill and besides that is going to pollute my model to a swamp!!
I ask this because i am using Nustache a port of MustacheJs to C#, .NET to render nested model.Anything that applies to Mustache also applies to Nustache
There's a few ways to do this.
In Javascript, if Mustache encounters a function in a value, it will call it using the enclosed text as the only argument.
var data = {
foo: function(text) { return '<b>' + text + '</b>'; }
}
mustache
{{#foo}}
HI I LIKE FISH, thanks.
{{/foo}}
outputs
<b>HI I LIKE FISH, thanks.</b>
Search for "lambda" in the mustache docs.
Another way to do it is do a falsey/truthy check.
data
{ foo: true }
mustache
{{#foo}}
output this if true.
{{/foo}}
{{^foo}}
output if false
{{/foo}}

Categories