Reduce number of if else statements? - javascript

I have some JavaScript, when a user enters in 10 digits in the phone field,it checks whether the country field has been populated so that it can assign a country code to it. See code below.
if (Country != null) {
var CountryName = Country[0].name;
var CountryId = Country[0].id;
var CountryType = Country[0].entityType;
if (CountryName == "United States of America") {
PhoneTemp = "+1 " + "(" + PhoneTemp.substr(0, 3) + ") " + PhoneTemp.substr(3, 3) + " - " + PhoneTemp.substr(6, 4);
} else if (CountryName == "India") {
PhoneTemp = "+91 " + PhoneTemp.substr(0, 4) + " " + PhoneTemp.substr(4, 6);
}
}
If i do it this way ill end up with a 100+ else if, is there a nicer way of doing it?

You can use switch or you can use Jquery $.inArray(val, array)
http://www.w3schools.com/js/js_switch.asp
http://api.jquery.com/jquery.inarray/

I would go for a map to abstract the country logic
var countryMap = {
'USA': usaLogic,
'FR': frLogic
};
function usaLogic(number) {
return "+1 " + "(" + number.substr(0, 3) + ") " + number.substr(3, 3) + " - " + number.substr(6, 4);
}
function frLogic(number) {
return ".....";
}
Then you can reduce your if statement to the following:
if (countryMap[CountryName]) {
PhoneTemp = countryMap[CountryName](PhoneTemp)
}

You can make an array or structure with countries and the phone prefix.
var Countries = ['India', 'France', 'Spain'];
var Prefixes = [91, 32, 34];
And with it you can save all if-else statements just calling the correct key in array.

Create a dictionary of country converters.
PhoneCountryConverters["India"] = function(PhoneTemp) { return "+91 " + PhoneTemp.substr(0, 4) + " " + PhoneTemp.substr(4, 6);}
usage:
PhoneTemp = PhoneCountryConverters[Country[0].name](PhoneTemp);
PhoneCountryConverters will have an entry for each country, and you eliminate if statements altogether.

Hi brother you can use two arrays like this :
var CountriesPrefix = {'usa': '+1','India': '+2', 'morocco': '+212'};
var Countries = ['usa', 'India', 'morocco'];
var CountryName='usa';
if($.inArray(CountryName, countries)==0){ //The country is in array
var PhoneTemp = countries_prefix[CountryName];
}
Using associative array here will reduce the pain of indexs between arrays by using the keys (the keys here are the Countries names).

Related

How can i get a certain amount of JSON data from an API?

pretty new programmer here, hopefully, this isn't too much of a rudimentary question, just couldn't find the answer anywhere (maybe I just don't know how to look?).
I'm currently working with the BandsInTown API and everything is working great, aside from the fact that I'm receiving way more objects than I need.
I would just like to know if there is a way that I can specify a certain number of objects that I want to receive back?
Any help is appreciated.
require("dotenv").config();
var keys = require("./keys.js");
var request = require('request')
var moment = require('moment')
var media = process.argv.slice(3).join(" ")
function bandsFunct() {
var artist = "";
for (var i = 3; i < process.argv.length; i++) {
if (i !== 3) artist += "-"
artist += process.argv[i];
}
if (process.argv[2] == "concert-this")
request("https://rest.bandsintown.com/artists/" + artist + "/events?app_id=codingbootcamp", function (error, response, body) {
console.log(response.body)
var body = JSON.parse(body)
console.log(" ")
console.log("-------------------------------------")
console.log(" ")
console.log("Upcoming concerts for " + artist + ": ");
for(var set in body) {
var date = moment(body[set].datetime).format("MM/DD/YYYY")
console.log(body[set].venue.city + ", " + "at " + body[set].venue.name + ", " + "on " + date)
}
console.log(" ")
console.log("-------------------------------------")
console.log(" ")
})
}
bandsFunct();
suppose you have a object
let obj = {
{ name: 'war', class :'12' , age: 21, field: 'cse' } ,
{ name: 'jar', class :'120' , age: 251, field: 'csee' }
}
if you want some selected fields you can do like this
var result = Object.keys(obj).filter(item =>
item.class < 100 // you can specify any condition
)
// the result will contain only those objects whose class < 100

Get full word containing a specific element

Having the reference to a specific DOM element (e.g. <mark>), how can we get the full word containing that element?
For example :
H<mark>ell</mark>o Wor<mark>l</mark>d, and He<mark>llo</mark>, <mark>Pluto</mark>!
I expect to get the following output :
First <mark>: Hello
Second: World
Third: Hello
Fourth: Pluto
var $marks = $("mark");
var tests = [
"Hello",
"World",
"Hello",
"Pluto",
];
function getFullWord($elm) {
// TODO: How can I do this?
// This is obviously wrong.
return $elm.html();
}
var $marks = $("mark");
tests.forEach(function(c, i) {
var word = getFullWord($marks.eq(i));
if (word !== c) {
alert("Wrong result for index " + i + ". Expected: '" + c + "' but got '" + word + "'");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
H<mark>ell</mark>o Wor<mark>l</mark>d, and He<mark>llo</mark>, <mark>Pluto</mark>!
If you need fast and compact code (one-liner), try this:
var $marks = $('mark');
$marks.each(function() {
var wholeWord = (this.previousSibling.nodeValue.split(' ').pop() +
this.textContent +
this.nextSibling.nodeValue.split(' ')[0]
).replace(/[^\w\s]/gi, '');
});
JSFiddle (with logging into console and comments)

Recursive Function not working correctly

I have a recusive function that is supposed to loop through a json object and output the expression. However, my recusion seems to be off because it's outputting field1 != '' AND field3 == '' when it should be outputting field1 != '' AND field2 == '' AND field3 == ''
I've tried a couple different things and the only way I can get it to work is by creating a global variable outstring instead of passing it to the function. Where am I off? When I step through it, i see a correct result but once the stack reverses, it start resetting outstring and then stack it back up again but leaves out the middle (field2).
JSFiddle
function buildString(json, outstring) {
var andor = json.condition;
for (var rule in json.rules) {
if (json.rules[rule].hasOwnProperty("condition")) {
buildString(json.rules[rule], outstring);
} else {
var field = json.rules[rule].id;
var operator = json.rules[rule].operator;
var value = json.rules[rule].value == null ? '' : json.rules[rule].value;
outstring += field + ' ' + operator + ' ' + value;
if (rule < json.rules.length - 1) {
outstring += ' ' + andor + ' ';
}
}
}
return outstring;
}
var jsonObj = {"condition":"AND","rules":[{"id":"field1","operator":"!= ''","value":null},{"condition":"AND","rules":[{"id":"field2","operator":"== ''","value":null}]},{"id":"field3","operator":"== ''","value":null}]};
$('#mydiv').text(buildString(jsonObj, ""));
The function has a return of a string.
When you call the function recursively from within itself, you aren't doing anything with the returned string from that instance, just calling the function which has nowhere to return to
Change:
if (json.rules[rule].hasOwnProperty("condition")) {
buildString(json.rules[rule], outstring);
}
To
if (json.rules[rule].hasOwnProperty("condition")) {
// include the returned value in concatenated string
outstring += buildString(json.rules[rule], outstring);
}
DEMO
Why so complicated?
function buildString(obj) {
return "condition" in obj?
obj.rules.map(buildString).join(" " + obj.condition + " "):
obj.id + " " + obj.operator + " " + string(obj.value);
}
//this problem occurs quite often, write a utility-function.
function string(v){ return v == null? "": String(v) }

How to setup if-statement with multiple conditions, which uses the valid condition's variable in the if-statement?

Okay, that title will sound a bit crazy. I have an object, which I build from a bunch of inputs (from the user). I set them according to their value received, but sometimes they are not set at all, which makes them null. What I really want to do, it make an item generator for WoW. The items can have multiple attributes, which all look the same to the user. Here is my example:
+3 Agility
+5 Stamina
+10 Dodge
In theory, that should just grab my object's property name and key value, then output it in the same fashion. However, how do I setup that if-statement?
Here is what my current if-statement MADNESS looks like:
if(property == "agility") {
text = "+" + text + " Agility";
}
if(property == "stamina") {
text = "+" + text + " Stamina";
}
if(property == "dodge") {
text = "+" + text + " Dodge";
}
You get that point right? In WoW there are A TON of attributes, so it would suck that I would have to create an if-statement for each, because there are simply too many. It's basically repeating itself, but still using the property name all the way. Here is what my JSFiddle looks like: http://jsfiddle.net/pm2328hx/ so you can play with it yourself. Thanks!
EDIT: Oh by the way, what I want to do is something like this:
if(property == "agility" || property == "stamina" || ....) {
text = "+" + text + " " + THE_ABOVE_VARIABLE_WHICH_IS_TRUE;
}
Which is hacky as well. I definitely don't want that.
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property;
}
If you need the first letter capitalized :
if(['agility','stamina','dodge'].indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per comment:
If you already have an array of all the attributes somewhere, use that instead
var myatts = [
'agility',
'stamina',
'dodge'
];
if(myatts.indexOf(property) !== -1){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
UPDATE per next comment:
If you already have an object with the attributes as keys, you can use Object.keys(), but be sure to also employ hasOwnProperty
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
var property = "agility";
var text = "";
if(Object.keys(item.attribute).indexOf(property) !== -1){
if(item.attribute.hasOwnProperty(property)){
text = "+" + text + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
Fiddle: http://jsfiddle.net/trex005/rk9j10bx/
UPDATE to answer intended question instead of asked question
How do I expand the following object into following string? Note: the attributes are dynamic.
Object:
var item = {};
item.attribute = {
agility:100,
stamina:200,
dodge:300
};
String:
+ 100 Agility + 200 Stamina + 300 Dodge
Answer:
var text = "";
for(var property in item.attribute){
if(item.attribute.hasOwnProperty(property)){
if(text.length > 0) text += " ";
text += "+ " + item.attribute[property] + " " + property.charAt(0).toUpperCase() + property.substr(1);
}
}
It's unclear how you're getting these values an storing them internally - but assuming you store them in a hash table:
properties = { stamina: 10,
agility: 45,
...
}
Then you could display it something like this:
var text = '';
for (var key in properties) {
// use hasOwnProperty to filter out keys from the Object.prototype
if (h.hasOwnProperty(k)) {
text = text + ' ' h[k] + ' ' + k + '<br/>';
}
}
After chat, code came out as follows:
var item = {};
item.name = "Thunderfury";
item.rarity = "legendary";
item.itemLevel = 80;
item.equip = "Binds when picked up";
item.unique = "Unique";
item.itemType = "Sword";
item.speed = 1.90;
item.slot = "One-handed";
item.damage = "36 - 68";
item.dps = 27.59;
item.attributes = {
agility:100,
stamina:200,
dodge:300
};
item.durability = 130;
item.chanceOnHit = "Blasts your enemy with lightning, dealing 209 Nature damage and then jumping to additional nearby enemies. Each jump reduces that victim's Nature resistance by 17. Affects 5 targets. Your primary target is also consumed by a cyclone, slowing its attack speed by 20% for 12 sec.";
item.levelRequirement = 60;
function build() {
box = $('<div id="box">'); //builds in memory
for (var key in item) {
if (item.hasOwnProperty(key)) {
if (key === 'attributes') {
for (var k in item.attributes) {
if (item.attributes.hasOwnProperty(k)) {
box.append('<span class="' + k + '">+' + item.attributes[k] + ' ' + k + '</span>');
}
}
} else {
box.append('<span id="' + key + '" class="' + item[key] + '">' + item[key] + '</span>');
}
}
}
$("#box").replaceWith(box);
}
build();
http://jsfiddle.net/gp0qfwfr/5/

Appending variables to a string in javascript

I am using prototype in my application but I am not sure how to add this correctly. Basically I have the following function and I need to construct the href of an anchor from which I already have the reference to a series of appended values
MyJavascriptClass.prototype.init = function() {
this.ToDate = $(this.Prefix + 'ToDate');
this.FromDate = $(this.Prefix + 'FromDate');
}
so in the following function I need to add those as parameters in the url attribute
MyJavascriptClass.prototype.btnClicked = function(evt) {
this.lnkShowLink.setAttribute('href', 'MyWebpage.aspx?StartDate=7/18/2012&EndDate=1/19/2012');
}
How can i do something like 'MyWebPage.aspx?StartDate=this.ToDate&EndDate=this.FromDate' ? Any help would be appreciated.
If you are using jquery, and $(this.Prefix + 'ToDate') and $(this.Prefix + 'FromDate') represent fields that contain values, then you can do this:
MyJavascriptClass.prototype.btnClicked = function(evt) {
this.lnkShowLink.setAttribute('href', 'MyWebpage.aspx?StartDate=' + this.ToDate.val() + '&EndDate=' + this.FromDate.val() + '');
}
It is difficult to tell from your code what they represent, and why you have them wrapped in $(..).
If ToDate and FromDate contain the two date values, then this should work...
'MyWebPage.aspx?StartDate=' + this.ToDate + '&EndDate=' + this.FromDate
If you don't know every properties:
var properties = [];
for(var i in this)
if(this.hasOwnProperty(i))
properties.push(i+'='+this[i]);
var url = 'MyWebPage.aspx?'+properties.join('&');
var string = "My name is: ",
name = "Bob",
punctuation = ".",
greeting = string + name + punctuation;
Or
var User = { name : "Bob", age : 32, sign : "Leo" },
welcome = "Hi, I'm " + User.name + ", and I'm " + User.age + " years old, I'm a " + User.sign + ", and I enjoy long walks on the beach.";

Categories