Undefined value from Object Literal (switch replacement) - javascript

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;

Related

push the total amount of objects to an array

I am trying to count how many times a specific item appears in an array. And then push that amount to an other array. I got the counter working, although when I push this amount to the array the type of this value turn out te be Not A Number...
Here is my code:
res2 =
0: (2) [29682885, "Jean-Paul"]
1: (2) [29682886, "DEMO Martin"]
2: (2) [29682887, "Johan"]
3: (2) [29682892, "Peter"]
4: (2) [29682900, "Antoine"]
5: (2) [29682902, "Sandra"]
6: (2) [29682906, "Kevin"]
7: (2) [29682910, "Wouter"]
8: (2) [29682911, "Tom"]
9: (2) [4, "Autotask"]
res3 =
0: (2) [29682885, "2019-05-16T08:25:32Z"]
1: (2) [29682885, "2019-07-01T13:11:00Z"]
2: (2) [29682885, "2019-07-03T10:21:07Z"]
3: (2) [29682885, "2019-09-03T14:00:45Z"]
4: (2) [29682885, "2019-09-11T09:59:07Z"]
5: (2) [29682885, "2019-09-17T14:13:39Z"]
6: (2) [29682885, "2019-10-09T16:48:41Z"]
7: (2) [29682885, "2019-10-30T13:48:12Z"]
8: (2) [29682885, "2019-10-30T14:13:01Z"]
9: (2) [29682885, "2019-10-30T14:34:13Z"]
10: (2) [29682885, "2019-11-07T13:41:27Z"]
11: (2) [29682885, "2019-11-22T12:41:08Z"]
...
res2.sort();
res3.sort();
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
console.log(person[1]);
} else {
person[1].occurrences++;
console.log(person[1]);
prepArray.push(person[1]);
}
prepArray.push(person[1]);
}
});
});
prepArray.push(person[1]); retruns an NaN somehow. But the console shows the exact amount I would like to push to my prepArray...
I've used a mix of filter, flat, map to achieve this. Added code comments to explain what logic is being used.
res2 = [[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"]]
res3 = [[29682885, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682885, "2019-09-17T14:13:39Z"],
[29682902, "2019-10-09T16:48:41Z"],
[4, "2019-10-30T13:48:12Z"],
[4, "2019-10-30T14:13:01Z"],
[29682911, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]];
// pick only the ids from res3
// this makes it easier for comparison
let res = res3.map(v => {
return v.shift();
}).flat()
let final = [];
// loop over res2, and count occurrences using .filter().length
res2.map(sale => final.push([sale[1], res.filter(person => person === sale[0]).length]));
console.log(final);
// if you want the output as an object,
// you can do the following
let finalObj = {};
res2.map(sale => finalObj[sale[1]] = res.filter(person => person === sale[0]).length);
console.log({ finalObj })
I've modified the input set (res3) slightly to show the difference in counts, the above code outputs the following,
[
[
"Jean-Paul",
5
],
[
"DEMO Martin",
0
],
[
"Johan",
0
],
[
"Peter",
0
],
[
"Antoine",
0
],
[
"Sandra",
2
],
[
"Kevin",
0
],
[
"Wouter",
0
],
[
"Tom",
3
],
[
"Autotask",
2
]
]
Edited my answer to get the desired output in object format, so now you'll get,
{
"Jean-Paul": 5,
"DEMO Martin": 0,
"Johan": 0,
"Peter": 0,
"Antoine": 0,
"Sandra": 2,
"Kevin": 0,
"Wouter": 0,
"Tom": 3,
"Autotask": 2
}
I don't understand many parts of your code, but trying to interpretate it:
res2 = [
[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"],
];
res3 = [
[29682911, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682902, "2019-09-17T14:13:39Z"],
[29682885, "2019-10-09T16:48:41Z"],
[29682885, "2019-10-30T13:48:12Z"],
[29682885, "2019-10-30T14:13:01Z"],
[29682885, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]
]
res2.sort();
res3.sort();
const prepArray = {};
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
}
prepArray[person[1]] = prepArray[person[1]] || 0;
prepArray[person[1]] += 1;
}
});
});
console.log(prepArray)

Angular -> Parsing JSON data into Chart.js bar chart

I have a problem. I have a list of data that I output grouped. Now I want to output the values e.g. erzeugenGes to a barchart. Chart modules itself works. Fail only at the grouped data for evaluation.
Enclosed my code and list
1,2,3,4,5,6,7,8,9,10,11,12 are the Month for the ChartLabels
1.
1: [{…}]
2: [{…}]
3: [{…}]
4: [{…}]
5: [{…}]
6: [{…}]
7: [{…}]
8: [{…}]
9: Array(1)
0: {jahr: 2020, monat: 9, erzeugungGes: 901.04, verbrauchGes: 952.22, eigenverbrauch: 515.24, …}
length: 1
__proto__: Array(0)
10: Array(2)
0:
bezogen: 252.18
eigenverbrauch: 201.62
eingespeist: 140.94
erzeugungGes: 342.53
jahr: 2019
monat: 10
verbrauchGes: 453.75
__proto__: Object
1:
bezogen: 232.07
eigenverbrauch: 174.13
eingespeist: 102.37
erzeugungGes: 276.48
jahr: 2020
monat: 10
verbrauchGes: 406.19
__proto__: Object
length: 2
__proto__: Array(0)
11: Array(1)
0: {jahr: 2019, monat: 11, erzeugungGes: 291.87, verbrauchGes: 761.16, eigenverbrauch: 238.38, …}
length: 1
__proto__: Array(0)
12: [{…}]
/// and Data
getData() {
this.ds.getAuswertungJahr().subscribe(res => {
this.daten = res;
this.data = this.daten.reduce((r, a) => { console.log("a", a); console.log('r', r); r[a.monat] = [...r[a.monat] || [], a]; return r; }, {}); console.log("group", this.data);
this.barChartData[0].data = [];
for (let i = 0; i < this.data.lenght; i++) {
this.barChartData[0].data.push(this.data[i]);
}
})
}
Thanks

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'
};

Organizing key value pairs value in comma separated fashion

I have two array like this:
var actval = [
0: "3"
1: "22-Nov-2018 15:32:36 IST"
2: "22-Nov-2018 15:32:40 IST"
3: "3"
4: "22-Nov-2018 15:32:36 IST"
5: "22-Nov-2018 15:32:40 IST"
6: "3"
7: "22-Nov-2018 15:32:36 IST"
8: "22-Nov-2018 15:32:40 IST"
]
var id = [
0: "STATUS"
1: "STARTTIME"
2: "ENDTIME"
3: "STATUS"
4: "STARTTIME"
5: "ENDTIME"
6: "STATUS"
7: "STARTTIME"
8: "ENDTIME"
]
What I want to do is make a final array which would have keys as STATUS, STARTTIME, ENDTIME and each of the keys can have multiple values like this:
finalarray = [
STATUS: ["3", "3", "3"]
STARTTIME: ["22-Nov-2018 15:32:36 IST", "22-Nov-2018 15:32:36 IST", "22-Nov-2018 15:32:36 IST"]
ENDTIME: ["22-Nov-2018 15:32:40 IST", "22-Nov-2018 15:32:40 IST", "22-Nov-2018 15:32:40 IST"]
]
For this I have tried this approach :
for (i = 0; i < id.length; i++) {
currentKey = id[i];
currentVal = actval[i];
result[currentKey] = currentVal;
}
but it only gives me one value for each key not every value:
How can i get the each value in that array linked to that key?
Solved Just adding one check in your code
try this:
var result = [];
for (i = 0; i < id.length; i++) {
let currentKey = id[i];
let currentVal = actval[i];
if(result[currentKey])
result[currentKey] = [...result[currentKey],currentVal];
else
result[currentKey] = [currentVal];
}
If actval always look like that and you want to extract the top 3 values you could just do a shift() something like this.
var final = {STATUS: [], STARTTIME:[], ENDTIME:[]};
for (let i=0; actval.length > i; i++) {
final.STATUS.push( actval.shift() );
final.STARTTIME.push( actval.shift() );
final.ENDTIME.push( actval.shift() );
}
What you are doing is just writing over the same array value with =.
You are always doing result['key'] = 'value';
Try this assuming actval is array not object:
finalobject = {
STATUS: actval.filter(e=>e.length===1),
STARTTIME: actval.filter((e, i)=>i%3).filter((e, i)=>i%2===0),
ENDTIME: actval.filter((e, i)=>i%3).filter((e, i)=>i%2!==0),
};
I will update question, when you will clarify some things and change this "arrays" to objects.

Replace javascript swich statement

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);

Categories

Resources