7 Replies - 2254 Views - Last Post: 19 November 2011 - 05:36 PM

#1 manleybruce  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 07-November 11

Why does it sometimes display 'undefined'

Posted 16 November 2011 - 10:36 AM

hi,

What happens is that when I click on a button, a random string from the RandomString variable appears below the button. e.g I click on the button and it displays 'AAB' and then if I click on the button again it may display 'AAE' and etc.

The problem is that sometimes it displays 'undefined'. I don't wanit 'undefined' to appear but why does it sometimes display 'undefined' rather than a Random string.

Below is the code:

<head>
        <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
        <title>Create a Session</title>
        <link rel="stylesheet" type="text/css" href="MyStyles.css">
        <script type="text/javascript">

	            
            	var randomStrings = [
        "AAA",
        "AAB",
        "AAC", 
        "AAD",
        "AAE",
    ];
 
    function getSession() {
    
var randomDiv = document.getElementById("randomStrings");

          randomIndex = Math.round((Math.random()*randomStrings.length-1));
          newText = randomStrings[randomIndex];
          randomDiv.innerHTML = newText;
}
</script>
</head>

<body>
<form action="create_session.php" method="post" name="sessionform">
          <p><strong>1: </strong><input id="sessionBtn" type="button" value="Get Session ID" name="sessionid" onclick="getSession()" />
          <div id="randomStrings"></div></p>  
</form>
</body>


Thank You

This post has been edited by manleybruce: 16 November 2011 - 10:42 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Why does it sometimes display 'undefined'

#2 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3730
  • View blog
  • Posts: 6,017
  • Joined: 08-June 10

Re: Why does it sometimes display 'undefined'

Posted 16 November 2011 - 11:20 AM

Operator Precedence

Quote

The multiplication operator ("*") has higher precedence than the addition operator ("+") and thus will be evaluated first.


Consider how this expression will be evaluated:
Math.round((Math.random()*randomStrings.length-1));

// Say Math.random() returns 0.06
// And randomStrings.length is 5
Math.round(0.06 * 5 - 1);

// Which gets evaluated to:
Math.round(0.3 - 1)

// Then:
Math.round(-0.7)

// Which ends up as -1, which gives you an "undefined"
// if you use it as an array element.



To fix this, use () to make it clear in which order to evaluate your expression:
Math.round( Math.random()* (randomStrings.length-1) );


Now this evaluates like this:
Math.round( Math.random()* (randomStrings.length-1) );

// Math.random() == 0.06
// randomStrings.length == 5
Math.round( 0.06 * (5 - 1) );

Math.round( 0.06 * 4 );

Math.round( 0.24 )

// Which ends up as 0, which is a valid index!


This post has been edited by Atli: 16 November 2011 - 11:23 AM
Reason for edit:: Wrong numbers xD

Was This Post Helpful? 3
  • +
  • -

#3 manleybruce  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 19
  • Joined: 07-November 11

Re: Why does it sometimes display 'undefined'

Posted 16 November 2011 - 11:53 AM

That has worked brilliantly. Did not expect a simple movement of a bracket makes the difference but it has. Well spotted and thanks for your help :)
Was This Post Helpful? 0
  • +
  • -

#4 JMRKER  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 130
  • View blog
  • Posts: 838
  • Joined: 25-October 08

Re: Why does it sometimes display 'undefined'

Posted 19 November 2011 - 07:07 AM

An alternative fix that does not involve the precedence would be:
<script type="text/javascript">
	                 
var randomStrings = [
    "AAA",
    "AAB",
    "AAC",
    "AAD",
    "AAE"   // NOTE: No comma after last entry of array
];
	 
function getSession() {
  var randomDiv = document.getElementById("randomStrings");
  randomIndex = Math.round(Math.random()*randomStrings.length);
  newText = randomStrings[randomIndex];
  randomDiv.innerHTML = newText;
}
</script>


:bananaman:

This post has been edited by JMRKER: 19 November 2011 - 07:11 AM

Was This Post Helpful? 0
  • +
  • -

#5 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3730
  • View blog
  • Posts: 6,017
  • Joined: 08-June 10

Re: Why does it sometimes display 'undefined'

Posted 19 November 2011 - 07:30 AM

@JMRKER
Actually, that' not correct. Removing the comma has no effect on the array. The only difference between your version and his is that your version has the possibility of going one index too high, whereas his has the possibility to go one too low.
Math.round(Math.random() * randomStrings.length);

// Say Math.random() returns 0.96
// And randomStrings.length is 5 (like before)
Math.round(0.96 * 5);
Math.round(4.8)
// == 5, which is one to far.



One thing that would "fix" both versions, without having to worry about the order of the calculations, would be to use Math.ceil and Math.floor in place of Math.round. - Neither of your versions will actually reach -1 or 5, so choosing in which direction to round the final value, rather than using the normal rules of rounding (that is: 0.5 is up and lower than that is down), would work around it.
Was This Post Helpful? 0
  • +
  • -

#6 JMRKER  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 130
  • View blog
  • Posts: 838
  • Joined: 25-October 08

Re: Why does it sometimes display 'undefined'

Posted 19 November 2011 - 12:49 PM

You're right. I had intended to use Math.floor(). Just flat out forgot to make the change!
My intent was: randomIndex = Math.floor(Math.random()*randomStrings.length);

Removing the ',' at the end does have the effect that if that element is
randomly selected (if the ',' is left as is) then the display will be blank.

To me, if I expect to see a string of three characters selected randomly,
then the result of a blank string is a problem for me. True it does not give
the "undefined" message, but to me that is better than an action that does
not show me anything.

Final decision goes to the OP. :bananaman:
Was This Post Helpful? 0
  • +
  • -

#7 Atli  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 3730
  • View blog
  • Posts: 6,017
  • Joined: 08-June 10

Re: Why does it sometimes display 'undefined'

Posted 19 November 2011 - 03:34 PM

View PostJMRKER, on 19 November 2011 - 07:49 PM, said:

Removing the ',' at the end does have the effect that if that element is
randomly selected (if the ',' is left as is) then the display will be blank.

That's not true.

First of all because variables that are not defined - such as missing array elements - are, by definition, "undefined". They won't display as an empty string, but as an "undefined" message. You would actually have to add an empty string for it to be displayed as such.

However, in this case that doesn't even apply, because Javascript simply ignores single extra commas at the end of an array declaration, meaning the index won't even be added with an undefined element. It simply won't exist, and will therefore result in an "undefined" message when called, just like any other non-existent index.

This is specifically mentioned in the ECMAScript specification:

Quote

Array elements may be elided at the beginning, middle or end of the element list. Whenever a comma in the
element list is not preceded by an AssignmentExpression (i.e., a comma at the beginning or after another
comma), the missing array element contributes to the length of the Array and increases the index of subsequent elements. Elided array elements are not defined. If an element is elided at the end of an array, that element does not contribute to the length of the Array


All the major browsers follow the specs on this.
Was This Post Helpful? 0
  • +
  • -

#8 JMRKER  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 130
  • View blog
  • Posts: 838
  • Joined: 25-October 08

Re: Why does it sometimes display 'undefined'

Posted 19 November 2011 - 05:36 PM

Looks like you are right again as this simple test shows. (Only tested in FF browser)

<script type="text/javascript">
var rs1 = [ "AAA", "AAB", "AAC", "AAD", "AAE", ];  // with ',' after last element
var rs2 = [ "AAA", "AAB", "AAC", "AAD", "AAE" ];   // without ',' after last element

var str1 = '';  for (var i=0; i<rs1.length; i++) { str1 += rs1[i]+'*'; } str1 += ' : '+rs1.length;
var str2 = '';  for (var i=0; i<rs2.length; i++) { str2 += rs2[i]+'*'; } str2 += ' : '+rs2.length;

alert(str1+'\n\n'+str2);
</script>

:detective:
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1