Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Javascript Program Question (code included)

Options
  • 07-12-2013 11:01pm
    #1
    Registered Users Posts: 225 ✭✭


    Hey guys, I am stuck on a javascript problem at the moment and would appreciate any help or insight you guys can give me.

    So the program takes a link from an input box in html, then reads the source code once the submit button is clicked, and extracts all hrefs in the source code.

    Then it individually goes through each href and finds, let's say, the first number in the source code of each href, adds this number to a total, and prints the total at the end of the program. The program itself is a little more complicated but I hope you can follow what I am trying to do here. Anyway, the problem I am bumping into is that when i enter a link and click the button, it returns the initial value or the variable total which is 0, as opposed to the updated value after the for loop has run. It seems like it executes the for loop a click too late, because when I click it again, it returns the proper total variable.

    On a slightly seperate note, the values being returned, for the same link have been inconsistent at times, does anyone know why that may be?
    var total = 0;
    
    $(document).ready(function () {
        $('#myButton').click(function () {
           getWebsite($('#inputField').val()); 
        });
    });
    
    function getWebsite(inUrl) {
        var url = inUrl;
    	$.get(url, function (data) {
    		var source = data;
    		var links = source.match(/<td><a href="(.*)">/g).slice(0,50);
    		for (var i = 0; i < links.length; i++){
    	        links[i] = "http://www.domain.com/" + links[i].split('"')[1]
    		$.get(links[i], function (data) {
    		var individualsource = $(data).find("div:nth-child(2) div div:nth-child(2) dd:nth-child(4)").html();
    		digit = individualsource.split("(")[0];
    		total += Number(digit);
    
    			});
    			};
    		$('div#output1').text(total);
    		});
    }
    
    
    


Comments

  • Technology & Internet Moderators Posts: 28,804 Mod ✭✭✭✭oscarBravo


    All the AJAX calls are asynchronous. The "total" value is being updated in the callback function of the nested $.get() calls, but you're updating the output1 div in the callback from the first $.get() call. In other words, you're updating the div while you're still waiting for the inner AJAX callback functions to increment the total value.

    You're going to need to wait until all the callbacks have run before you update the output1 div. One possibility is to increment a global counter each time you make a $.get() function call, and decrement it in each callback function. When it's decremented to zero, that's the last callback, so update output1. Alternatively, update output1 in all the callback functions with the current value of total - you'll see it count up, but that might not be a bad thing.


  • Registered Users Posts: 225 ✭✭TheSetMiner


    oscarBravo wrote: »
    All the AJAX calls are asynchronous. The "total" value is being updated in the callback function of the nested $.get() calls, but you're updating the output1 div in the callback from the first $.get() call. In other words, you're updating the div while you're still waiting for the inner AJAX callback functions to increment the total value.

    You're going to need to wait until all the callbacks have run before you update the output1 div. One possibility is to increment a global counter each time you make a $.get() function call, and decrement it in each callback function. When it's decremented to zero, that's the last callback, so update output1. Alternatively, update output1 in all the callback functions with the current value of total - you'll see it count up, but that might not be a bad thing.

    I have done it like that before where I see it count up but the thing is I will need to use that variable in other functions and it just takes its value as zero each time which is incorrect. I'm not sure I understand what you are saying about the callbacks. I have only programmed in python before js and after a for loop the variable is updated for future use. This isn't the case here and I'm finding that a little confusing. Is there any relatively simple way of updating the variable globally to the value directly after the for loop?

    Thank you very much for the reply


  • Technology & Internet Moderators Posts: 28,804 Mod ✭✭✭✭oscarBravo


    Again: AJAX is asynchronous. That means that you send a HTTP request, and tell it that when that request returns to call the callback function for you - the "function (data)" that you've passed as the second argument to each $.get() call.

    That means that the callback function doesn't get called when the get() method runs; it gets called whenever the HTTP request invoked by that get() method happens to return a response. It could be a few milliseconds later, it could be ten seconds later - but as you have written the script, you're not waiting for those requests to return responses that will execute the callback functions, you're firing off the requests and immediately updating a div with a value that won't be populated until all the callback functions have run, whenever that might happen to be.

    There's one other thing you could do: replace $.get() with calls to $.ajax(), and set async to false in the settings argument - this will cause the script to stop and wait for each AJAX call to complete before continuing. It would be better to comprehend the event-driven nature of AJAX however, and deal with it accordingly.


  • Registered Users Posts: 225 ✭✭TheSetMiner


    Decided to just let the numbers tally up as the program goes along. Included a loading gif then to ensure the user is aware that the numbers are still being calculated. Thanks for your help


  • Technology & Internet Moderators Posts: 28,804 Mod ✭✭✭✭oscarBravo


    Decided to just let the numbers tally up as the program goes along. Included a loading gif then to ensure the user is aware that the numbers are still being calculated.
    Good call. Another possible approach to consider is to show a progress bar, and increment it each time a callback is run. The value of the progress bar is ((the total number of get requests minus the number of callbacks that have run) divided by the total number of get requests).
    Thanks for your help
    No problem.


  • Advertisement
Advertisement