1

I have at ready a function with inside ajax call that extrapolates values from MySql database. Then, in .scroll() event, i have a function that use thise values to animate some divs.

The problem is that sometimes .scroll() is run when ajax call is not finished.

function values_database(){
    $.ajax({    
     type: "POST",  
     url: 'events.php', 
     dataType:"json",   
     data: {
        dal_mese1: 'example'
     },
     success: function (result) { 
      var return_php = JSON.parse(JSON.stringify(result));  
      values.push(return_php); //VALUES FOR ANIMATIONS
     }
 }

 $(window).scroll(function(){
        var top_window2 = $(window).scrollTop();
        var bottom_window2 = top_window2 + $(window).height();                      
        var top_statistiche = $('#somedivs').offset().top;  
        if(((top_statistiche >= top_window2) && (top_statistiche <= bottom_window2))){  
            animation_somedivs();
        }   
 });

function animation_somedivs(){
//use values global array (with inside value from database, if ajax call is finish before "this" function is run
}

How can i solve this problem ? (I don't want to use async: false)

Thanks a lot and sorry for my english

Borja
  • 3,359
  • 7
  • 33
  • 66

3 Answers3

2

Basically if you want to run something after request finish, you can put it into success callback. So minor modification of your code can do what you want

function values_database(){
    $.ajax({    
     type: "POST",  
     url: 'events.php', 
     dataType:"json",   
     data: {
        dal_mese1: 'example'
     },
     success: function (result) { 
      var return_php = JSON.parse(JSON.stringify(result));  
      values.push(return_php); //VALUES FOR ANIMATIONS

      $(window).scroll(function(){
        var top_window2 = $(window).scrollTop();
        var bottom_window2 = top_window2 + $(window).height();                      
        var top_statistiche = $('#somedivs').offset().top;  
        if(((top_statistiche >= top_window2) && (top_statistiche <= bottom_window2))){  
            animation_somedivs();
        }   
      });

     }
 }

function animation_somedivs(){
    //use values global array (with inside value from database, if ajax call is finish before "this" function is run
}

Edit

In case if your ajax request runs more than once per page load, you're going to need some modification.

function handle_scroll() {
    var top_window2 = $(window).scrollTop();
    var bottom_window2 = top_window2 + $(window).height();                      
    var top_statistiche = $('#somedivs').offset().top;  
    if(((top_statistiche >= top_window2) && (top_statistiche <= bottom_window2))){  
        animation_somedivs();
    }   
  }
}
function values_database(){
    $.ajax({    
     type: "POST",  
     url: 'events.php', 
     dataType:"json",   
     data: {
        dal_mese1: 'example'
     },
     success: function (result) { 
      var return_php = JSON.parse(JSON.stringify(result));  
      values.push(return_php); //VALUES FOR ANIMATIONS

      $(window).off('scroll', handle_scroll);
      $(window).on('scroll', handle_scroll);

     }
 }

function animation_somedivs(){
    //use values global array (with inside value from database, if ajax call is finish before "this" function is run
}
Andrey
  • 4,020
  • 21
  • 35
  • 4
    Mostly OK, but isn't this attaching an event handler at every AJAX request success? – keul Aug 30 '18 at 12:33
  • @LucaFabbri you are absolutely right. It does. I figured that this is ajax request only performed once, but it's not guaranteed, of course. – Andrey Aug 30 '18 at 12:35
  • so you can probably edit the answer using http://api.jquery.com/one/ maybe? – keul Aug 30 '18 at 12:37
  • @LucaFabbri `one` will not be suitable here, I beleive – Andrey Aug 30 '18 at 12:41
1

$.ajax returns a promise you can check for in your scroll event handler:

var promise;
function values_database(){
    promise = $.ajax({    
     type: "POST",  
     url: 'events.php', 
     dataType:"json",   
     data: {
        dal_mese1: 'example'
     },
     success: function (result) { 
      var return_php = JSON.parse(JSON.stringify(result));  
      values.push(return_php); //VALUES FOR ANIMATIONS
     }
 }

 $(window).scroll(function(){
        $.when(promise).then(function(){
            var top_window2 = $(window).scrollTop();
            var bottom_window2 = top_window2 + $(window).height();                      
            var top_statistiche = $('#somedivs').offset().top;  
            if(((top_statistiche >= top_window2) && (top_statistiche <= bottom_window2))){  
                animation_somedivs();
            }
        });

 });

function animation_somedivs(){
//use values global array (with inside value from database, if ajax call is finish before "this" function is run
}
schellmax
  • 5,678
  • 4
  • 37
  • 48
1

Andrei solution bind a function to scroll event for each ajax call you do. You can use a global variable to know if ajax call is complete, as you can see from code above.

var ajaxCallIsComplete = false;

function values_database(){
$.ajax({    
 type: "POST",  
 url: 'events.php', 
 dataType:"json",   
 data: {
    dal_mese1: 'example'
 },
 success: function (result) { 
  var return_php = JSON.parse(JSON.stringify(result));  
  values.push(return_php); //VALUES FOR ANIMATIONS
  ajaxCallIsComplete = true;
 }
}

 $(window).scroll(function(){
    if (!ajaxCallIsComplete){
        return;
    }
    var top_window2 = $(window).scrollTop();
    var bottom_window2 = top_window2 + $(window).height();                      
    var top_statistiche = $('#somedivs').offset().top;  
    if(((top_statistiche >= top_window2) && (top_statistiche <= bottom_window2))){  
        animation_somedivs();
    }   
});

function animation_somedivs(){
   //use values global array (with inside value from database, if ajax call is finish before "this" function is run
}