Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    Regular Coder d'Anconia's Avatar
    Join Date
    Jan 2010
    Location
    Tempe, AZ
    Posts
    149
    Thanks
    16
    Thanked 6 Times in 6 Posts

    Trouble Passing Variables to Function (Called by setTimeout)

    Okay so I am having the following problem. I have gotten AJAX to work and am trying to get Javascript to fade out an old review score and fade in with a new score. The important part right now is that when I try to run it I get the following error:

    Code:
    Uncaught ReferenceError: preciseResponseAverage is not defined
    (anonymous function)
    The following is my current code:

    Code:
    function starSubmitFxn(starNumber) {
        function fadeIn(average, color){
            'use strict';
            var ratingAverage = document.getElementById('rating_average');
            ratingAverage.innerHTML = (average);
            //now time to change the ratings color
            var entityRating = document.getElementById('rating');
            entityRating.style.color = color;
            window.color = color;
        }
        'use strict';
        window.fade('rating');
        //setTimeout("fade('rating')", 1000);
        var ajax = getXMLHttpRequestObject();
        if (ajax) {
                    var currentUsername = '<?php echo $current_username; ?>';
                    var currentEntityId = <?php echo $entity_id; ?>;
                    // Create the Ajax object:
                    
                    ajax.onreadystatechange = function () {
                        if (ajax.readyState === 4) {
                            //Check the status code:
                            if ( (ajax.status >= 200 && ajax.status < 300) || (ajax.status === 304) ) {
                                
                                //document.getElementById('ajax_status').innerHTML = ajax.responseText;
                                
                                var starResponse = JSON.parse(ajax.responseText);
                                                            
                                var starResponseNumber = parseInt(starResponse["1"].value);
                                var starResponseAverage = (parseInt(starResponse["1"].average));
                                var preciseResponseAverage = starResponseAverage.toPrecision(2);
                                var starResponseColor = starResponse["1"].newColor;
                                
                                //var ratingDiv = document.getElementById('rating');
                                
                                U.removeEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating("<? echo $current_user_review_rows['review_score'] ?>", 'blue'); } );
                                U.addEvent(U.$('star_rating_div'), 'mouseout', function(){ newStarRating(starResponseNumber, 'blue'); } );
                                    if (!isNaN(starResponseNumber)) {
                                                                            
                                        //newStarRating(ratingNumber, "blue");//end of newStarRating call
                                            var i = null;
                                            for (i = 1; i <= 10; i++) {
                                            document.getElementById('rating_star_' + i).src = '../images/white_star_17px.png';
                                            } //end of star color reset
    
                                            var j = null;
                                            for (j = 1; j <= starResponseNumber; j++) {
                                                document.getElementById('rating_star_' + j).src = '../images/blue_star_17px.png';
                                            }
                                        
                                        } //end of response text check
                                    if(!isNaN(preciseResponseAverage)) { //if a number is returned, time to fade out / in
                                        
                                        setTimeout("fadeBackIn(preciseResponseAverage, starResponseColor)", 400);
                                        
                                    }
                                } //end of Ajax connectivity check
                                else { //if Ajax status text is a failure
                                    
                                    }
                            } //end of Ajax ready state
                        }; //end of function for execution on ready state change
                        
                    var data = 'currentUsername=' + encodeURIComponent(currentUsername) + '&currentEntityId=' + encodeURIComponent(currentEntityId) + '&starNumber=' + encodeURIComponent(starNumber);
                    ajax.open('POST', '../resources/star_submit.php?' + data, true);
                    ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    
                    ajax.send(data);
            } //end if ajax object exists
            else {
                
            } //end if it doesn't exist
        } //end of starSubmitFxn
    There are some functions defined outside of this function but I don't think those are necessary for me to post right now. The issue seems to be that I'm not sure how to properly send a variable to a function when that function is called via setTimeout. Any help would be appreciated. Thank you.
    Datagonia Web (My Portfolio)

    Powerful ideas for all lovers of personal and political freedom:
    Freedomain Radio
    Free Talk Live

  • #2
    Master Coder felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    6,642
    Thanks
    0
    Thanked 649 Times in 639 Posts
    setTimeout expects a function as the first parameter so the string you supply is effectively being wrapped in an anonymous function that is run after the specified time.

    The preciseResponseAverage variable is only defined in the anonymous function attached to the onreadystatechange event handler and so that copy has gone out of scope by the time that your string gets converted into a function.

    Converting it to a function yourself so that the fields it references are visible before they go out of scope will hopefully create the needed closure.

    setTimeout(function() {fadeBackIn(preciseResponseAverage, starResponseColor)}, 400);
    Stephen
    Learn Modern JavaScript - http://javascriptexample.net/
    Helping others to solve their computer problem at http://www.felgall.com/

    Don't forget to start your JavaScript code with "use strict"; which makes it easier to find errors in your code.

  • #3
    Regular Coder d'Anconia's Avatar
    Join Date
    Jan 2010
    Location
    Tempe, AZ
    Posts
    149
    Thanks
    16
    Thanked 6 Times in 6 Posts
    Yeah I decided the best way to do it was to modify and use a setTimeout function within a for loop. For some reason it seems like it is not going through the loop correctly though. Here is the relevant part of my code:

    Code:
        function fade(currentTime, newAverage, newColor) {
            if (currentTime <= 5){
                var currentOpacity = 1.0 - (currentTime * .2);
                document.getElementById('rating').style.opacity = currentOpacity;
                document.getElementById('logo').style.width = "500";
            }
            if(currentTime >= 5){
                var ratingAverage = document.getElementById('rating_average');
                ratingAverage.innerHTML = (newAverage);
                //now time to change the ratings color
                var entityRating = document.getElementById('rating');
                entityRating.style.color = newColor;
                var currentOpacity = currentTime * 2 - 1.0;
                document.getElementById('rating').style.opacity = currentOpacity;
                }
            }   
    
    document.getElementById('rating').style.opacity = 1.0;                 
    for (var timer = 0; timer < 10; timer++){
        setTimeout(function(){fade(timer, preciseResponseAverage, starResponseColor)}, 100);
        }
    I was hoping for a slow fade but am not getting that. Currently it's not even changing the opacity at all when I click on it, nor the color of the text. In fact I added the logo.style.width = 500 line specifically to test to see whether it's even looping at all and it appears that it's not because the logo on the page is not changing to 500px (whether I include the 'px' or not). It's will change the actual rating itself though...

    Edit: Heck I even got it to change the color but when it changes there is no opacity fade at all. It's like Javascript is only executing the final part of the loop or something...

    PS For the record I am using Chrome.
    Last edited by d'Anconia; 01-24-2013 at 08:15 AM.
    Datagonia Web (My Portfolio)

    Powerful ideas for all lovers of personal and political freedom:
    Freedomain Radio
    Free Talk Live

  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    27,206
    Thanks
    80
    Thanked 4,566 Times in 4,530 Posts
    I don't think you understand what this code is doing:
    Code:
    for (var timer = 0; timer < 10; timer++)
    {
        setTimeout(function(){fade(timer, preciseResponseAverage, starResponseColor)}, 100);
    }
    That code is saying "Repeat 10 times: 100 milliseconds from *RIGHT NOW* call the fade function."

    It is *NOT* saying "call the fade function 10 times, each time 100 milliseconds after the last".

    So all 10 calls to fade( ) are being made...but they are *ALL* being made at essentially the same time.
    So the human eye only sees the result of the last call.

    But it would be trivial to have it do that:
    Code:
    for (var timer = 0; timer < 10; timer++)
    {
        setTimeout(
            function(){ fade(timer, preciseResponseAverage, starResponseColor)}, 
            100*(timer+1)
        );
    }
    You see that?
    The first call to fade will be at 100*(0+1) milliseconds.
    The second call to fade will be at 100*(1+1) milliseconds.
    ...
    The 10th call to fade will be at 100*(1+9) milliseconds, or 1 full second later.

    Is this the best way to do it? Probably not. But it's workable.
    Last edited by Old Pedant; 01-24-2013 at 08:29 AM.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    27,206
    Thanks
    80
    Thanked 4,566 Times in 4,530 Posts
    This doesn't make much sense:
    Code:
            if (currentTime <= 5){... }
            if (currentTime >= 5){ ... }
    So if currentTime is *exactly* 5, you will do *BOTH* actions. And for the most part, the second one will negate the effects of the first.

    Is that *really* what you wanted?

    Wouldn't it make more sense to do
    Code:
            if (currentTime < 5){... }
            else { ... }
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    27,206
    Thanks
    80
    Thanked 4,566 Times in 4,530 Posts
    And, yes, you *MUST* specify "px" when changing a style property if you want the number to be interpreted as pixels. MSIE will default to pixels, but other browsers will just ingore the number. Remember, you can use "pt" and "%" and a few other things other than "px", so the browser insists you tell it which.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •