Replace javascript swich statement - javascript

I have a switch in javascript that I need to put it different.
How can I write this in a better way to avoid the switch?
var types = {
Int: 2,
Short: 3,
Long: 4,
Double: 5,
Decimal: 6,
String: 1,
Guid: 10,
Variant: 11,
};
switch (data.columnTypeId) {
case types.String:
case types.Guid:
case types.Variant:
self.GetStrings(data);
break;
case types.Int:
case types.Decimal:
case types.Short:
case types.Long:
case types.Double:
self.GetNumbers(data);
break;
default:
}

What about doing the same map, but map a function reference instead?
var columnTypes = {
2: self.GetNumbers,
3: self.GetNumbers,
4: self.GetNumbers,
5: self.GetNumbers,
6: self.GetNumbers,
1: self.GetStrings,
10: self.GetStrings,
11: self.GetStrings,
0: self.GetDefault //Guessing the default value would be 0
};
columnTypes[data.columnTypeId](data);
or with a safe check:
if (columnTypes.indexOf(data.columnTypeId) !== -1) {
columnTypes[data.columnTypeId](data);
} else {
self.GetDefault(data);
}
Or as #dandavis pointed out in a comment:
columnTypes[data.columnTypeId || self.getDefault](data);

Related

How to handle multiple adSlots from GPT togheter with prebid.js

Im migrating from Adnuntius too GPT and are using prebid.js
I need diffrent slots on each page and when im trying to define them, i only get them to work if i have diffrent sizes on each slot.Lets say that i use 970x250 on the first one and change the second one to 300x250 it will work.
I Think my issue is somewhere where i define the slots, or maybe with our adunit?
I want to be able to use the same size for all slots.
site_level is our adunit name from gpt
var div_sizes_l = [[970, 250], [980, 200], [980, 240]];
var PREBID_TIMEOUT = 1000;
var FAILSAFE_TIMEOUT = 3000;
var adUnits = [
{
code: 'div-gpt-ad-Landing_Top',
mediaTypes: {
banner: {
sizes: div_sizes_l,
}
},
bids: [
{
bidder: 'rubicon',
params: {
accountId: '20562',
siteId: '2153438',
zoneId: '11258332'
}
}
]
},
//
{
code: 'div-gpt-ad-Landing_Middle',
mediaTypes: {
banner: {
sizes: div_sizes_l,
}
},
bids: [
{
bidder: 'rubicon',
params: {
accountId: '20562',
siteId: '2153438',
zoneId: '11258344'
}
},
]
},
];
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function() {
googletag.pubads().disableInitialLoad();
});
var pbjs = pbjs || {};
pbjs.que = pbjs.que || [];
pbjs.que.push(function() {
pbjs.addAdUnits(adUnits);
pbjs.requestBids({
bidsBackHandler: initAdserver,
timeout: PREBID_TIMEOUT
});
});
function initAdserver() {
if (pbjs.initAdserverSet) return;
pbjs.initAdserverSet = true;
googletag.cmd.push(function() {
pbjs.que.push(function() {
pbjs.setTargetingForGPTAsync();
googletag.pubads().refresh();
});
});
}
// in case PBJS doesn't load
setTimeout(function() {
initAdserver();
}, FAILSAFE_TIMEOUT);
googletag.cmd = googletag.cmd || [];
googletag.cmd.push(function() {
googletag.defineSlot('/21855748559/site_level',
div_sizes_l,
'div-gpt-ad-Landing_Top').addService(googletag.pubads());
googletag.pubads().setTargeting('position', 'Landing_Top');
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
googletag.cmd.push(function() {
googletag.defineSlot('/21855748559/site_level',
div_sizes_l,
'div-gpt-ad-Landing_Middle').addService(googletag.pubads());
googletag.pubads().setTargeting('position', 'Landing_Middle');
googletag.pubads().enableSingleRequest();
googletag.enableServices();
});
Your prebid code is correct, it will be able to use that variable for all sizes in the auction across both adunits. However, because you are using Rubicon, this is why there is a problem. Their adapter specifically requires an array of adunit sizes ID#s for them to then read and pass you a bid response of the right size. [See here for their docs] (http://prebid.org/dev-docs/bidders/rubicon.html). Example:
{
bidder: 'rubicon',
params: {
accountId: '20562',
siteId: '2153438',
zoneId: '11258332',
sizes: [15, 3, 2]
}
}
As well here is their sizeMap for you to reference to pass the correct size IDs to them, this was pulled straight from their [adapter source] (https://github.com/prebid/Prebid.js/blob/master/modules/rubiconBidAdapter.js):
var sizeMap = {
1: '468x60',
2: '728x90',
5: '120x90',
8: '120x600',
9: '160x600',
10: '300x600',
13: '200x200',
14: '250x250',
15: '300x250',
16: '336x280',
17: '240x400',
19: '300x100',
31: '980x120',
32: '250x360',
33: '180x500',
35: '980x150',
37: '468x400',
38: '930x180',
39: '750x100',
40: '750x200',
41: '750x300',
42: '2x4',
43: '320x50',
44: '300x50',
48: '300x300',
53: '1024x768',
54: '300x1050',
55: '970x90',
57: '970x250',
58: '1000x90',
59: '320x80',
60: '320x150',
61: '1000x1000',
64: '580x500',
65: '640x480',
66: '930x600',
67: '320x480',
68: '1800x1000',
72: '320x320',
73: '320x160',
78: '980x240',
79: '980x300',
80: '980x400',
83: '480x300',
94: '970x310',
96: '970x210',
101: '480x320',
102: '768x1024',
103: '480x280',
105: '250x800',
108: '320x240',
113: '1000x300',
117: '320x100',
125: '800x250',
126: '200x600',
144: '980x600',
145: '980x150',
152: '1000x250',
156: '640x320',
159: '320x250',
179: '250x600',
195: '600x300',
198: '640x360',
199: '640x200',
213: '1030x590',
214: '980x360',
221: '1x1',
229: '320x180',
232: '580x400',
234: '6x6',
251: '2x2',
257: '400x600',
264: '970x1000',
265: '1920x1080',
278: '320x500',
288: '640x380'
};

angular foreach problems when adding new items

I have an angular application with Firebase. I want to change the value of an firebase item. Everytime the total KM changes it needs to be set to the right value. so this is my services:
countKm(){
this.totalKmRef = this.db.list(this.uid + '/rides');
this.totalKm$ = this.totalKmRef.valueChanges();
this.totalKm$.subscribe(res=> this.getAllRides(res));
}
getAllRides(res){
this.rides = res;
this.rides.forEach(ride =>{
this.uniqueRides.push(ride.km);
})
this.totalKm = this.uniqueRides.reduce(this.sum);
localStorage.setItem("totalKm", this.totalKm);
}
sum(a, b){
return a += b;
}
Now for some reason, when i add a ride everything is fine, but the second time everything goes wrong.
for example the first time the foreach runs i get (after firebase has already 5 items):
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
}
After i run the foreach 1 time my object list is like this:
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
5: 5,
}
After add a new value the second time and further the foreach does this:
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
5: 5,
6: 5,
7: 5,
8: 5,
9: 5,
10: 5,
11: 5,
12: 5,
}
Is there some one who can help me? I think it's a wrong configuration in the foreach but can't find out where.
Thanks for you help!
this.uniqueRides.push(ride.km); is just pushing additional items into the array.
Either check to see if the ride is included .includes
this.rides.forEach(ride => {
if(!this.uniqueRides.includes(ride)) {
this.uniqueRides.push(ride.km);
}
})
or clear the array out every time. this.uniqueRides = []

Check object for exact field match and only true values

How can I check if an object has the exact elements with true values?
This should be valid...
var checkIt = { 4: true, 15: true, 30: true, 75: true, id: 'anyString' };
...while those are invalid:
var checkIt = { 4: true, 15: false, 30: true, 75: true, id: 'anyString' };
var checkIt = { 4: true, 15: true, id: 'anyString' };
As a result I need true/false for this check.
One possible approach (ES6):
var props = [4, 15, 30, 75];
var isValid = props.every((prop) => checkIt[prop] === true);
... or, ES5 version:
var isValid = props.every(function(prop) {
return checkIt[prop] === true;
});
With this you can easily adjust the list of properties to check. Using every makes sure the check drops out right after encountering the first invalid property.
Note: you aren't quite clear on whether or not each property should be exactly true or just truthy; I assumed the former. If that's not the case, just drop === true part.

Undefined value from Object Literal (switch replacement)

So, I'm a javascript n00b. Have heard that case/switch statements are...passé. I'm trying to wrap my head around object literals as their replacement structure.
After searching and trying various iterations in my code, I still cannot figure out why the "switch" variable value is coming back as "undefined". In my limited experience, a variable with a value of "undefined" usually means that it has no value, right? Is it a variable scope issue?
From what I gather the code is doing is creating a object (mod). The mod object has properties with the name of [3-18]. Each of these properties have values which are functions. These functions return a string value.
Here's what I've got so far:
function getModValue(str) {
var search = str;
var mod = {
3: function() {return "-3";},
4: function() {return "-2";},
5: function() {return "-2";},
6: function() {return "-1";},
7: function() {return "-1";},
8: function() {return "-1";},
9: function() {return "0";},
10: function() {return "0";},
11: function() {return "0";},
12: function() {return "0";},
13: function() {return "+1";},
14: function() {return "+1";},
15: function() {return "+1";},
16: function() {return "+2";},
17: function() {return "+2";},
18: function() {return "+3";}
}
mod[search]();
}
alert(getModValue("14"));
Here is my (non)working example: jsfiddle
Thanks in advance for your help.
The error is just you forgot the return at the end.
I think you are overengineering. This works and it's much more simple:
function getModValue(str) {
var mod = {
3: "-3",
5: "-2",
4: "-2",
6: "-1",
7: "-1",
8: "-1",
9: "0",
10: "0",
11: "0",
12: "0",
13: "+1",
14: "+1",
15: "+1",
16: "+2",
17: "+2",
18: "+3"
}
return mod[str];
}
alert(getModValue("14"));
PS: Checking a 3d6 roll?
UPDATE: Think that mod is a map, where the keys are numbers and the values are strings. When you look for a value using the key, Javascript has to compare your key with the existing ones. Check the following:
var number="1";
number==1 //true, because it's like if '==' makes a "toString()"
number===1 //false
var myObj={hello: function(){ return "Hello";}};
myObj.hello();
myObj["hello"](); // equivalent
const responseToParse = {
3: '-3',
4: '-2',
5: '-2',
6: '-1',
7: '-1',
8: '-1',
9: '0',
10: '0',
11: '0',
12: '0',
13: '+1',
14: '+1',
15: '+1',
16: '+2',
17: '+2',
18: '+3',
19: undefined,
20: null
}
const MyObjectLiteralLibrary = {
3: response => response[3],
4: response => response[4],
5: response => response[5],
6: response => response[6],
7: response => response[7],
8: response => response[8],
9: response => response[9],
10: response => response[10],
11: response => response[11],
12: response => response[12],
13: response => response[13],
14: response => response[14],
15: response => response[15],
16: response => response[16],
17: response => response[17],
18: response => response[18],
19: response => response[19],
20: response => response[20]
}
let str
str = 14
console.log(MyObjectLiteralLibrary[str](responseToParse))
str = 19
console.log(MyObjectLiteralLibrary[str](responseToParse))
str = 20
console.log(MyObjectLiteralLibrary[str](responseToParse))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Nice one; Yes, object literals are better than a switch when some of the cases returning an undefined or a specific cases only. This can be done through switch but will leave a fall-through in many cases.
I played around and came up with this logic in ES6 format. Please look into the code snippet above if that helps.
You can loop over defaultList of cases or a set of required cases. Also, If you want to parse a JSON object this is very helpful.
You have missed return on last line of your api.
return modsearch;

Javascript array indexed by string

I have the below javascript function I want to optimise for my web app.
function DisplayToolTip(str) {
switch (str) {
case "a":
this.tooltip(xvalue,yvalue,text);
break;
case "b":
this.tooltip(xvalue,yvalue,text);
break;
case "c":
this.tooltip(xvalue,yvalue,text);
break;
default: break;
}
}
The switch statement may change i.e. json may need to add in a case "d" but the function exists so dont know how to update the above.
Normally in c# I would use a dictionary, so key would be "a" and value would be an object with properties xvalue,yvalue,text or value would be a string "this.tooltip(xvalue,yvalue,text);".
This way I could update the dictionary and the execution speed of 'DisplayToolTip' would be relatively the same no matter how many elements.
How do you create an array of objects indexed or quickly found using a string value in javascript?
Objects in javascript are like dictionaries.
var dictionary = {
a : ["xvalue","yvalue","text1"],
b : ["xvalue","yvalue","text2"]
}
console.log(dictionary["b"][2]); // will give you text2.
Demo
EDIT: Updated answer to contain arrays (as that is what the question is).
You can use the switch statement itself, with fall-through:
switch (str) {
case "a": case "b": case "c":
this.tooltip(xvalue,yvalue,text);
break;
default: break;
}
(But, as Qantas commented, the default case isn't necessary here.)
Or, it the browser supports it, you can use the indexOf method of arrays:
if (["a", "b", "c"].indexOf(str)) ...
I would do something like this:
var tooltipSettings={
a: {xvalue: 1, yvalue: 1, text: 'string a'},
b: {xvalue: 2, yvalue: 2, text: 'string b'},
c: {xvalue: 3, yvalue: 3, text: 'string c'}
};
function DisplayToolTip(str) {
if(tooltipSettings[str])
{
var settings=tooltipSettings[str];
this.tooltip(settings.xvalue, settings.yvalue, settings.text);
}
}
You could use a dictionary, witch is basically an plain object.
Javascript allows you to access an object property by string like you would access an array property like this:
var obj = {
test: 'text',
b: 4
}
console.log(obj['test'], obj.test);
console.log(obj['b'], obj.b);
So your code would look like this:
var pairs = {
'a': {
xvalue: 1,
yvalue: 1,
text: '1111'
},
'b': {
xvalue: 2,
yvalue: 2,
text: '2222'
}
};
function DisplayToolTip(str) {
var prop = pairs[str];
if (typeof prop !== 'undefined')
return this.tooltip(prop.xvalue, prop.yvalue, prop.text);
throw 'undefined prop ' + str;
}

Categories

Resources