Auto-enumeration in Javascript - javascript

I want to create C type enumerations, values automatically starting from 0.
What is wrong with the following code?
function ArrayToEnum(arr)
{
var len = arr.lenght;
en = {};
for(i=0;i<len;i++)
en[arr[i]]=i;
return en;
}
a=['foo','bar'];
b=ArrayToEnum(arr);
console.debug(b.foo);
> Undefined
I expect it to print 0 but instead(at least in Chromium 9.0) this is undefined. If instead of calling the function, I apply the body directly, it works:
var l=a.length;
for(i=0;i<l;i++) b[a[i]]=i;
console.debug(b.foo);
> 0
What is wrong with the function?

If that's your actual code, "length" is misspelled as "lenght" in the third line:
var len = arr.lenght;
I'd expect that to compile, but it would set len equal to undefined, which would prevent your loop body from executing at all. That would result in arr.foo a.k.a. arr["foo"] being undefined, as you're seeing in your output.
Also you're passing "arr" to ArrayToEnum() when your array in the previous line is called a, not arr.
The common theme here is that when you start talking about a variable you haven't defined yet. JavaScript "helpfully" defines it instead of telling you it doesn't exist yet.
I tried it in the Chrome JS console, and I got "reference error" until I fixed the "a"/"arr" problem. Once that was fixed, I got "undefined" as you describe.
When I fixed "lenght", bingo, it prints "0".

Related

Why can't I assign an empty code block to a variable in Javascript?

I'm using V8 (via Chrome) to test this. In Javascript, a code block evaluates to whatever the last value in the code block evaluates to. I wanted to see what would happen if I assigned a variable to an empty code block.
// example of code block evaluating to last value in the block
> {1;2;3};
3
// This won't work, it returns an empty object,
// not an empty code block.
> var emptyBlock = {};
> emptyBlock;
Object object
Eventually, I figured out how to specify that I want an empty code block, not an empty object.
> {;}
undefined
> {;;}
undefined
> {;;;;;}
undefined
Okay, beautiful, so an empty code block resolves to undefined. Right?
Not exactly!
> var emptyBlock = {;}
Uncaught SyntaxError: Unexpected token ';'
?! Now it is unclear whether the empty code block actually returns undefined, or something else entirely is at play. If it merely did evaluate to undefined, we would expect the above assignment to work.
Does anyone know why this is happening?
Eventually, I figured out how to specify that I want an empty code block, not an empty object.
This is largely determined by what is before the {, not after it.
Since you have an = before it, you are in a context where { is the start of an object literal. A ; is not allowed where a property name is expected, so the code errors.
You can't assign blocks. They aren't values, they are parts of the code structure.
Both of these seem demonstrably false. var codeBlockValue = {1;2;3}; for example works perfectly fine, and sets codeBlockValue to 3
No, it doesn't:
var codeBlockValue = {1;2;3};

Split not working in javascript ,Uncaught TypeError

Can someone explain me why if condition in this code isn't working?
var zaposleni=[];
for(i=1;i<brOpcija;i++){
zaposleni.push(myOpts[i].value);
}
var zaposleniRestoran=[];
for(i=1;i<brOpcija;i++){
if(zaposleni[i].split(' ').slice(2).join(' ') == vrednostSelekta()){
zaposleniRestoran.push(zaposleni[i].split(' ').slice(0,2));
}
}
Here,i have array zaposleni where i push some values,and array is look like ["name" "surname" "restaurantName"],and then i am checking if restaurantName == vrednostSelekta() (where vrednostSelekta() is return value of some function in javascript),but i always get this error:
Uncaught TypeError: Cannot read property 'split' of undefined
at HTMLSelectElement.<anonymous> (zaposleni.js:51)
at HTMLSelectElement.handle (jquery.min.js:55)
at HTMLSelectElement.o (jquery.min.js:49)
But when i erase this if,and then type that in debugger,i get no error and it is working there..Thanks in advance!
Looks like the "zaposleni" array is empty or maybe there is only one element in it. Your for loop is starting at "i=1".
In the error, Cannot read property 'split' of undefined means that you're calling .split(...) to something that isn't defined.
This means that at the beginning of the if, the script is stopping when zaposleni[i] is not defined.
This is probably because i is bigger than the length of zaposleni at the biggest value for i, as you're iterating up to the same value, but you're starting to push at i=1 rather than i=0, as array indices in JS start at 0. In other words, you're adding a value at zaposleni[0], not zaposleni[last index value], and requiring from zaposleni[1] up to zaposleni[last index value], so the last one will be undefined.
The issue may also be that myOpts[i].value is probably undefined for some values of i, so I would recommend checking that

Loop through object with multidimensional array

I use promises in angular to get some data from the server. In promises success I do
promise.success(function (data, status) {
for (i = 0; i <= data.data.length; i++){
$scope.anArray[i] = data.data[i][1] ;
}
}
I do this because data that came from the server have this structure
{"result":"answered","data":[["jake","508"],["amir","602"],["ben","450"]]}
and I ONLY want to get the numbers 508 , 602 and 450. But I always get the same error TypeError: Cannot read property '0' of undefined reffering to this line : $scope.anArray[i] = data.data[i][0] ;.
Those numbers are feeded to a library to create a chart. Sometimes the chart is created, some times is not. Even if it is created, the same error is always there.
I dont know how to fix that error and getting the chart to be always created without any problems. Looks like the code doesnt like the data.data[i][0] structure, having a simple array like data.data[i] doesnt create an error.
What should I do?
Thanks
Your for loop has an extra execution. You've initialized i to 0 but you've also used <= which means you are going to execute on array[array.length] which is out of bonds. That returns undefined and when you try to access the [0] index on that undefined you get that error.
Change to
for (i = 0; i < data.data.length; i++){
If you're able to do assignment personally I would go with
$scope.anArray = data.data.map(entry => entry[1]);
and skip the for loop entirely. Note if you want to avoid lambdas this would be
$scope.anArray = data.data.map(function(entry) { return entry[1]; });

JQuery val returning undefined

So I'm calling the following function:
function updateOutput(a){
var n = $('#selector').val();
$('#hueslide').val(a[n].hue);
$('#huetext').val(a[n].hue);
}
And I'm getting an error: "Cannot read property 'hue' of undefined."
However, when I use console.log(n), it's returning a value. And when I manually insert the same value in a[n], I get the expected result. I'm guessing this is an asynchronous issue, but the same code was working in an earlier version and I'm not sure how to fix it.
Specifically, when trying to debug updateOutput using console.log, I get the following:
console.log(n); //returns 0
console.log(a); //returns an array of objects
console.log(a[0]); //returns first object in array
console.log(a(n)); // returns undefined
That error isn't saying that n is undefined, or even a, it's saying that there is no property hue on whatever is assigned to a[n]. Whatever you are passing into updateOutput has no key to match n that also has the property hue.
Try like this:
function updateOutput(a){
$(document).ready(function(e) {
var n = $('#selector').val();
$('#hueslide').val(a[n].hue);
$('#huetext').val(a[n].hue);
});
}
You have to wait until the element are fully loaded. That's why you have to use ready method.
Okay, I figured it out. Turns out the value of 0 in n I was passing a string. So adding n = parseInt(n); resolved the issue.

reference json numeric key with variable in javascript

How to loop through this data: (I have no control over format)
{"rowCount":3,"1":{"K":"2009","V":"Some Data"},"2":{"K":"2010","V":"More Data"}}
Above is a console.log(results) and results is a string
var r = JSON.parse(results);
var t;
for(var i=1;i<=r.rowCount;i++) {
t=r[i].V;
tableData.push(
{title:t, year:'2009', hasChild:true, color: '#000'}
);
}
Error: TypeError: 'undefined' is not an object (evaluating 'r[i].V')
I cannot get it to evaluate the variable i. What am I doing wrong?
Thanks
UPDATE
The incoming data had a bad rowcount causing the error. The accepted answer however is correct... just user error on my part not catching the bad incoming data. Had I put a console.log inside the loop I would have realized the error was actually happening after two successful loops. oops
I assume r.rowCount should be j.rowCount.
Ideally you should also initialise the i variable if you haven't already (i.e. with the var keyword).
(I've also moved the var t declaration outside the loop, to make it clear that it's the same t throughout and you're just changing its value. You shouldn't redeclare it with var each time – although I doubt this affects the output.)
var j = {"rowCount":2,"1":{"K":"name","V":"john"},"2":{"K":"name","V":"sue"}};
var t;
for (var i = 1; i <= j.rowCount; i++) {
t = j[i].V;
console.log(t);
}
Working demo – JSFiddle

Categories