0

I'm trying to get a variable (lib) out of a multiple nested functions.

var nme='name',lib;

$('script').each(function(){

    var src=$(this).attr('src');

    if(typeof(src)==='undefined'){src='';}

if(src.indexOf(nme)!==-1){

    $.get($(this).attr('src').match(/\w([^ ]+)spbin/)[0]+'/conf/ptmedia.plist',
        function(c){
            $(c).find('key').each(function(){
                if($(this).html()==='MediaLib'){lib=$(this).next().html();}
            });
        }
    );

}
});

if(lib==='some lib'){DO STUFF}
Aleksov
  • 1,200
  • 5
  • 17
  • 27
  • 4
    Ajax is **asynchronous**! Move `$('.null').html(lib);` into the success callback. More information here: http://stackoverflow.com/q/14220321/218196. – Felix Kling Mar 25 '13 at 18:49
  • Why can't you just... Wait what's wrong?: This should work fine. – Christian Stewart Mar 25 '13 at 18:49
  • 1
    Are you really trying to load scripts via ajax to look up something in their source code? Then you're doing something wrong. – Bergi Mar 25 '13 at 18:57

2 Answers2

4

Your problem isn't with scoping, the problem is that you have an AJAX call which is asynchronous. You should put the change of HTML in .null inside the callback function instead:

$.get($(this).attr('src').match(/\w([^ ]+)spbin/)[0]+'/conf/ptmedia.plist',
        function(c){
            $(c).find('key').each(function(){
                if($(this).html()==='MediaLib'){lib=$(this).next().html();}

                $('.null').html(lib);
            });
        }
});

In JavaScript often IO is asynchronous. This means that when you make an AJAX call it does not happen immidiately but rather waits for the value to return from the HTTP request and then calls a callback. In your case that function(c) is the callback, it gets executed when the value of the AJAX call arrived.

So in fact you were updating the HTML content of .null to undefined, since it got the value of lib before it was updated.

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • +1 but you should explain what this means – Christian Stewart Mar 25 '13 at 18:50
  • It works, but i need get this variable in another place – Aleksov Mar 25 '13 at 18:54
  • @Aleksov in that case you need to make sure the callback happened by then. JavaScript runs (usually, there are ways around this) in a _single thread_, every iteration it checks all the events that happen (like an AJAX returned value) and runs code based on them. If you need your lib variable available it _MUST_ be in that callback. If you feel like you're getting messy code you can move it into a method. – Benjamin Gruenbaum Mar 25 '13 at 18:55
  • @Aleksov: As long as the other code is run after the response is received, everything is fine. You just have to make sure that it does. – Felix Kling Mar 25 '13 at 18:55
  • I once solved this very same issue on SO (for somebody else), but did totally mess up on explaining why it happened. This explanation is great, wish I could give you +5. – 11684 Mar 25 '13 at 18:57
  • To down-voter, care to explain what I can improve with this answer, and which parts you did not like? – Benjamin Gruenbaum Mar 25 '13 at 19:12
0

I solved this problem as follows:

var nme='name';

    $('script').each(function(){

    var src=$(this).attr('src');

        if(typeof(src)==='undefined'){src='';}

        if(src.indexOf(nme)!==-1){media=$(this).attr('src').match(/\w([^ ]+)spbin/)[0];}

    });


    function ffn(){
    $($.ajax({url:media+'/conf/ptmedia.plist',async:false}).responseText).find('key').each(function(){
        if($(this).html()==='string'){value=$(this).next().html();}
    });

    return value;
    }

    if(ffn()==='some lib'){DO STUFF}

Thank you all for your participation and good ideas!

Aleksov
  • 1,200
  • 5
  • 17
  • 27
  • Hi, using synchronous AJAX is usually a bad solution. It blocks the browser until it arrives (meaning for example, the window can be unresponsive (stuck) for 10 seconds) and it is generally not practical. I would reconsider. – Benjamin Gruenbaum Mar 26 '13 at 23:00
  • @BenjaminGruenbaum Hi! Thank you for your comment! Perhaps you could offer another solution? – Aleksov Mar 26 '13 at 23:03
  • I did :) In my answer, also, it turns out this question is a duplicate of another one, you might want to also check the answers there – Benjamin Gruenbaum Mar 26 '13 at 23:03
  • @BenjaminGruenbaum I do not think it is a duplicate, because the problem here Neuve AJAX, but how to make the variable of nested functions. While I do not see a way out. Maybe you can help me in solving this problem – Aleksov Mar 26 '13 at 23:06
  • The scope was never a problem, it was syncronization. See my answer – Benjamin Gruenbaum Mar 26 '13 at 23:10