0

I am trying to create a recursive function in Javascript. But in order to loop my XML file properly I am trying to pass the right value taken from the XML length and pass it to the setTimeout function. The problem is that the setTimeout ( setTimeout('cvdXmlBubbleStart(nextIndex)', 3000); )function does not get the value of nextIndex and thinks it is undefined. I am sure I am doing something wrong.

jQuery(document).ready(function($) {
cvdXmlBubbleStart('0');
});

function cvdXmlBubbleStart(nextIndex) {
    $.ajax({
        url: "cross_video_day/xml/broadcasted.xml",
        dataType: "xml",
        cache: false,
        success: function(d) {
            broadcastedXML = d;
            cvdBubbleXmlProcess(nextIndex);
        }
    });
}

function cvdBubbleXmlProcess(nextIndex) {
    var d = broadcastedXML;
//console.log(nextIndex);
    var length = $(d).find('tweet').length;
    if((nextIndex + 1) < length) {


    nextIndex = length - 1;


    $(d).find('tweet').eq(nextIndex).each(function(idx) {
        var cvdIndexId = $(this).find("index");
        var cvdTweetAuthor = $(this).find("author").text();
        var cvdTweetDescription = $(this).find("description").text();
        if (cvdTweetAuthor === "Animator") {
            $('#cvd_bubble_left').html('');
            obj = $('#cvd_bubble_left').append(makeCvdBubbleAnimator(cvdIndexId, cvdTweetAuthor, cvdTweetDescription));
            obj.fitText(7.4);
            $('#cvd_bubble_right').html('');
            setTimeout('$(\'#cvd_bubble_left\').html(\'\')', 3000);
        } else {
            $('#cvd_bubble_right').html('');
            obj = $('#cvd_bubble_right').append(makeCvdBubble(cvdIndexId, cvdTweetAuthor, cvdTweetDescription));
            obj.fitText(7.4);
            $('#cvd_bubble_left').html('');
            setTimeout('$(\'#cvd_bubble_right\').html(\'\')', 3000);
        }

    });

         }else{
         $('#cvd_bubble_left').html('');
            $('#cvd_bubble_right').html('');
         }    
        //broadcastedXMLIndex++;
        setTimeout('cvdXmlBubbleStart(nextIndex)', 3000); 
}
  • Try to pass a function to `setTimeout` instead of a string: `setTimeout(function(){cvdXmlBubbleStart(nextIndex);}, 3000)` – basilikum Jun 17 '13 at 22:31
  • Has string support been removed? Not saying it's a good idea, but [last time I checked it still worked](https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout). – Dave Newton Jun 17 '13 at 22:33
  • OP: You should use the function as shown in streetlogics' answer. As written you'd need to *construct* the string, e.g., `"cvdXmlbubbleStart('" + nextIndex "')"`. Although it baffles me why you'd use a string if it's an index. – Dave Newton Jun 17 '13 at 22:35
  • @DaveNewton no, string support is there but it depends on where the string is evaluated. The string doesn't remember its closure. – basilikum Jun 17 '13 at 22:36
  • @basilikum The string doesn't need to--the string just needs to be appropriately built using the value of nextIndex. Still broken in terms of what should be done, but should work. – Dave Newton Jun 17 '13 at 22:36
  • @DaveNewton - That would work as well. – Travis J Jun 17 '13 at 22:37
  • @DaveNewton sure, that's a possible solution. But passing the name of the variable in the string as OP did it doesn't work because the string is not evaluated where it was created. – basilikum Jun 17 '13 at 22:38
  • @basilikum Which is why I showed how to make it work--*I* know why it didn't work, but I wanted the OP to understand that it *could* work, and that it shouldn't be done like that--but that it's doable. – Dave Newton Jun 17 '13 at 22:40
  • @DaveNewton Well your question just sounded like you were wondering why the string version didn't work and why people suggest passing a function instead. – basilikum Jun 17 '13 at 22:46

2 Answers2

2

Checkout How can I pass a parameter to a setTimeout() callback? - basically you need to pass an anonymous function to the set timeout call

setTimeout(function(){
    cvdXmlBubbleStart(nextIndex)
}, 3000); 
Community
  • 1
  • 1
streetlogics
  • 4,640
  • 33
  • 33
  • Are strings no longer supported? [It's still shown as doable on MDN](https://developer.mozilla.org/en-US/docs/Web/API/window.setTimeout). – Dave Newton Jun 17 '13 at 22:34
  • @DaveNewton - strings are supported, they go into the `Function` constructor – Travis J Jun 17 '13 at 22:36
2

Using an anonymous function will work because it shares the same scope as nextIndex.

setTimeout(function(){cvdXmlBubbleStart(nextIndex);}, 3000); 

The reason that your current code does not work for you is because when you use a string inside of the setTimeout function it uses the Function constructor to create a function based on the string passed (which is similar to using eval and is not best practice). What is worse here is that the function created with Function will not share the same scope as where it was created and thus not have access to nextIndex.

Travis J
  • 81,153
  • 41
  • 202
  • 273