String variable prefixed with undefined in for loop - javascript

I have a drop-down on which i use .Change() to trigger a function. Function basically get certain data using getJSON and based on those value in have to create string of array for mp3 file.
Below code is generating string but always prefix undefined to string.
In code you will notice setTimeout which is just to provide certain delay till data received. In below example i am using static value and it still prefix undefined. not sure why may be i have defined variable in wrong manner.
Complete example JSBin
$('.customSurah').change(function(){
//surahNo = $('#surah option:selected').val();
setTimeout(function(){
//countSpan = $('#surah-wrapper').children().length;
surahNo = 1;
countSpan = 7;
var i=0;
for (i = 0; i <= countSpan; i++) {
strCat += surahNo+"/"+i+".mp3,";
console.log(strCat);
}
}, 3000);
});
OUTPUT
undefined114/0.mp3,
undefined114/0.mp3,114/1.mp3,
undefined114/0.mp3,114/1.mp3,114/2.mp3,
undefined114/0.mp3,114/1.mp3,114/2.mp3,114/3.mp3,
undefined114/0.mp3,114/1.mp3,114/2.mp3,114/3.mp3,114/4.mp3,
undefined114/0.mp3,114/1.mp3,114/2.mp3,114/3.mp3,114/4.mp3,114/5.mp3,
undefined114/0.mp3,114/1.mp3,114/2.mp3,114/3.mp3,114/4.mp3,114/5.mp3,114/6.mp3,

You have a variable strCat that is not initialized, and then you append a value to it in this line:
strCat += surahNo+"/"+i+".mp3,";
Since strCat is not initialized in first round of loop, you get undefined prepended to your string.
To fix this, you need to initialize the variable to empty value first:
var strCat = ''; // <- initialize your variable to empty value
surahNo = 1;
countSpan = 7;

The outcome is perfectly valid as per javascript is concerned.
Why?
I guess you probably know if you declare any variable in javascript and you don't assign its default value then automatically undefined is assigned. So, that is a valid. What happens when you do that:
var somevar; // non assigned default value set to -> undefined
console.log(somevar); // logs undefined
But,
In your case you have to give it a default value like a blank string var strCat "";. So, now when you do this:
var somevar = ""; // assigned default value to set to -> ""
console.log(somevar); // logs ""
So, the solution to your issue is, you have to initialize/assign a default value to your variable. like:
var strCat = "";

Related

When iterating through array, first value is always "undefined"

I created a quiz and I'm trying to iterate through the elements in the HTML form (radio buttons), adding the value of the button to a string if it is checked. However, the first thing added to the string is always "undefined" and I can't work out why. Please note, I'm very new to Javascript.
I've tried changing the way the for loop works - using (inputs.length+1), or setting i to 1 instead of 0. This doesn't seem to be the issue however. I've also tried checking that the value isn't undefined before adding it to the string (as shown below), but it still results in the first part of the string saying "undefined".
var chosen_result; //the string to add values to
var temp;
var inputs = document.forms["townquiz"].elements;
for (i = 0; i < (inputs.length-1); i++) {
temp = inputs[i];
if((temp.checked) && !(temp.value == "undefined")){
chosen_result += temp.value;
Actual Result: undefinedABC
Expected Result: ABC
where A, B and C are values of the radio buttons in the HTML form.
In regards to strings, the += operator concatenates the current value and a new value. chosen_result is undefined because it was declared but not initialized. Simply set chosen_result to an empty string:
var chosen_result = ""; //the string to add values to
var temp;
var inputs = document.forms["townquiz"].elements;
for (i = 0; i < (inputs.length-1); i++) {
temp = inputs[i];
if((temp.checked) && !(temp.value == "undefined")){
chosen_result += temp.value;
Assign an empty string to chosen_result like chosen_result = '' to avoid the value being undefined when you append to it.
String addition in JavaScript can be somewhat strange, because it uses coercion. When you declare chosen_result, you're not setting it to anything, so its type is undefined. When you add a string to undefined, JavaScript will turn it into a string, then concatenate it. String(undefined), however, is "undefined", so, what you're really doing is
"undefined" += "ABC"
To fix this problem, initialize chosen_result as an empty string:
var chosen_result = ""
This way, it won't be coerced.

How to change a variable used as argument for function

I've looked around a little bit, and I haven't found a clear answer as to why when this proceeding code is ran, it returns myInt as 0. I've read posts about how the variable is only changed inside the function, but from my perspective, I don't see any reason why myInt cannot be changed. For refrence, this is in Javascript.
var myInt = 0;
function changeVar(x) {
x += 1;
}
changeVar(myInt);
console.log(myInt);
The reason myInt is not changing is that x has local scope (anything you do to x only affects the value of x inside of changeVar).
Here's how you could change myInt from changeVar():
var myInt = 0;
function changeVar() {
myInt += 1;
}
changeVar();
console.log(myInt);
If you want to change a variable by passing it as an argument, you should pass an object instead:
var myObject1 = {value: 0}
var myObject2 = {value: 10}
function changeVar(x) {
x['value'] += 1;
}
console.log(myObject1['value']);
console.log(myObject2['value']);
changeVar(myObject1);
console.log(myObject1['value']);
console.log(myObject2['value']);
I will expand on the example given by #N.Kern - here is a better example of how to change the initial variable passed in the function:
var myInt = 0;
function changeVar(x) {
return x += 1;
}
var y = changeVar(myInt);
console.log(y);
Now, the reason for this is offered by #Shekhar Chikara in the comment. Essentially, the value you're passing to the function is modified within the local scope of the function, but it's not actually assigned back (or saved in memory) to the globally declared variable. So when you log the original global variable, you get the unchanged value back. Thus, you want to simply save your functions' returned value to it's own variable.
This will get you started on researching more.
Hope this helps.

why doesn't this return an l-value?

Maybe ReSharper or visual studio is wrong, but I don't think that this returns an r-value. I also don't think it actually sets the property in the $parent controller:
function getParentItem(path) {
var obj = $scope.$parent;
var param = null;
var items = path.split(".");
for (var i = 0; i < items.length; i++) {
var item = items[i];
var split = item.split("(");
if (split.length === 2) {
param = split[1].replace(/[\)\']/g, "");
}
obj = obj[split[0]];
}
if (param == null) {
var thisObj = obj;
return thisObj;
} else {
return { obj: obj, param: param };
}
}
If I do this:
getParentItem($scope.someProperty) = "yadda"
I get error marked by probably ReSharper and I think it doesn't actually set the new value
As Amy/Volkan said your code is not valid but I think I get what you want to do. There are lots of ifs but here it goes:
if your $scope.someProperty is string property that you want to reassign on result of the function getParentItem, and your function returns object that can have that param ($scope.someProperty), first you need to figure out which path you pass in but it looks like it's some string separated by dots.
// so then assign result of the function to some variable
// you need to pass somePath to function
let parentItem = getParentItem(somePath);
// then change that property
parentItem[$scope.someProperty] = "yadda";
or another possibility what you might need would be:
parentItem.param[$scope.someProperty] = "yadda";
then do whatever you want with parentItem like put it on $scope or whatever.
If you want better help please do some jsfiddle or something.
The problem is (and I slap my head on how stupid I was) that the leaf branches of this $scope object aren't objects themselves, and in some cases in our code they don't even exist yet. You get so used to $scope being an object you fail to realize that the final elements can't possibly be objects at least in Javascript.
So the solution was to pass the value that I wanted to set as a parameter:
function getParentItem(path, optionalValue)
On the final loop of the parent search, if optionalValue is passed, I can then set the value onto the object:
obj[--last parameter name--] = optionalValue;

Referencing a number in a JavaScript multidimensional object

The code I have below uses a number as a dataset in a JavaScript object:
spacenum = spacedetails[1];
//Create object for space number
if(spacenum in spaceobj['P1'] == false){
spaceobj['P1'][spacenum] = {}; // must initialize the sub-object, otherwise will get 'undefined' errors
}
spaceobj['P1'][spacenum]['Vacant'] = spacedetails[2];
spaceobj['P1'][spacenum]['Name'] = spacedetails[3];
spaceobj['P1'][spacenum]['Number'] = spacedetails[4];
spaceobj['P1'][spacenum]['Apartment'] = spacedetails[5];
This code goes around in a loop so 'spacenum' starts at 1 and goes up to the late 100s.
I am trying to access the data like so:
console.log(spaceobj.P1.11.Vacant);
However, the '11' is throwing up errors. I've tried brackets and quotes without any luck.
How can I access the data I want using a number?
In javascript '11' is not a valid variable name. However, because of its dynamic nature you can use:
console.log(spaceobj.P1["11"].Vacant);
Alternatively, one can also use:
console.log(spaceobj["P1"]["11"].Vacant);
Actually your line code below is undefined
spaceobj['P1']
Be sure your spaceobj['P1'] = false; has value
spacenum = 11;
spaceobj = [];
spaceobj['P1'] = false;
spaceobj['P1'][spacenum]= 'A';
spaceobj['P1'][spacenum]= 'B';

Undefined variable? encrypt/decrypt

Hey i am trying to make a simple encrypt/decrypt javascript. I am having a lot of trouble using variables from my first function into the second function.
the first function encrypts
2nd function decrypts
problem: I cannot use the variables I used in my first function. For example for "encoded" it keeps returning undefined! I attached my short code under.
var encoded;
function code(string, pass)
{
array=[]
for (var i = 0; i<string.length; i++)
{
//converts code into an array & unicode
b = (string.charCodeAt(i))
array.push(b)
}
//encovder
let encoded = array.map(function(x)
{
return x*pass
})
return encoded
}
(code("hello",7))
//decode
function decoded()
{
console.log(encoded)
}
console.log(decoded())
You should assign the value of the function to your variable in the relevant scope:
var encoded;
function code(string, pass){
array=[]
for (var i = 0; i<string.length; i++){
//converts code into an array & unicode
b = (string.charCodeAt(i))
array.push(b)
}
//encovder
let encoded = array.map(function(x){
return x*pass
})
return encoded
}
encoded = (code("hello",7));
By the way your result will be NaN because "hello".charCodeAt(5) is NaN and NaN * number == NaN.
Because you don't set the variable encoded that is defined on the first line, thus it value will be undefined when you try to log it.
WHY?
because inside code you redefine encoded on this line let encoded = ... and the later one shadows the one defined on the first line. So, here the second one gets set and not the first one (global one).
How to solve this?
You either not declare a new encoded inside the function (so this let encoded = ... should become this encoded = .... Or assign the returned value of code to the global encoded like this var encoded = code("hello", 7);.
An example of Variable Shadowing:
var value = 5;
console.log(value); // uses the above value
function foo(){
var value = 99; // redefining value (shadowing occur from this point)
console.log(value); // logs the newly defined value.
}// at this point, the value (99) gets destroyed.
foo();
console.log(value); // logs 5 as it is the one belonging to this scope no matter wether the value (99) gets destroyed or not.
Read more about Scopes and Variable shadowing and Variables lifetime.

Categories

Resources