Javascript "Promise"s being broken

I hope this doesn't turn into a treatise.

On a click of a link I'm using jQuery to get the counter value next to it to use in an SQL lookup.
That's done in function loadTables(event).
I do some other simple stuff like create a unique # to append to the resulting populated HTML file that I save temporarily.
The AJAX code works fine, returning a valid URL.

Still within that function I call a function clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id) that does the AJAX for me and returns the path to the page I want to .load.

A-synchronicity was causing the null page to load before the AJAX returned, so I bravely/boldly/blundered into "promise"s.

I got my promise code layout c/o the 42 line sample here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

When you see the code, the if/then enclosing the promise and AJAX is to keep other blank forms of same kind loading; for the purpose of seeing something happen when I show my boss later today.

You'll see a commented out jQuery .load that works, so substituting the not-waited-for resolved promise IS certainly my problem.
The two alerts, (containing "new_url=" and "Past .load") both happen before the AJAX is done, even thought I though they would now wait.

What tweak am I missing here?
// =================================================================================================
// As per set up in function RightMargin(), this responds to table links clicked in the right margin

function loadTables(event)  
{
  event.preventDefault() ;
  var thislink=$(this).attr('href') ;              // The URL of the link clicked
  var destination='#' + $(this).data('target');    // The TARGET of the link clicked
  
  var id_of_rowno='#' + $(this).data('link');      // Add'l info in the <input> element
  var rowno = $(id_of_rowno).val() ;               // Reads the value the the counter
  
  var tablename= $(this).data('link');  // Use this value, ~ RtMgn_tablename
  tablename = tablename.substring(6) ;  // to extract the table whose data must be loaded
  
  // getRandomIntInclusive(min, max)                        // Thinking (now) that I'll populate the form
  var uniq_file_id = getRandomIntInclusive(1, 9999999999) ; // and have to save it uniquely before loading it
  
  // This function will do the AJAX and return the page to load the the form populated 
  // after the SQL activity
  // However when I run this, I'm getting the alert messages below as the very first thing,
  // before it even call this function!!!
  // ENTER PROMISES
  
  var new_url = "" ;
  
  if (tablename=="Modem")
    {
    // =================================================================
    var maybe = new Promise(
      
      // The resolver function is called with the ability to resolve or
      // reject the promise
      
      function(resolve, reject) 
      { 
        new_url = clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id) ; 
        resolve(new_url) ;
      }    // EO function for resolve or reject
    ) ;  // EO Promise defined
    
    maybe.then(
        // Log and use the fulfillment value
        function(new_url) {
          alert("new_url="+new_url) ; 

          // Load the file
          // $(destination).load("http://10.139.164.191/Cell_Modems/public_html/temp/modem_table_3671212420.html", function( response, status, xhr ) 
          $(destination).load(new_url, function( response, status, xhr )  
          {
            if ( status == "error" ) 
            {
              var msg = "Sorry but there was an error: ";
              alert( msg + xhr.status + " " + xhr.statusText );
            }  // EO IF
          }) ;  // EO Callback for load AND load method itself
          alert("Past .load") ;
        })
    .catch(
        // Log the rejection reason
        function(reason) {
            console.log('Handle rejected promise ('+reason+') here.');
        });

    
  }  // EO IF "Modem"
  else
  {
    // Load the file  (will be changed from this in the near future, once I get ajax deferred/promised/bleah!)
    $(destination).load(thislink, function( response, status, xhr )  
    {
      if ( status == "error" ) 
      {
        var msg = "Sorry but there was an error: ";
        alert( msg + xhr.status + " " + xhr.statusText );
      }
    }) ; 
  }  // EO else not "Modem"
}  // EO function loadTables(event)

Open in new window


Thank you!
RalphAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Dave BaldwinFixer of ProblemsCommented:
I've never heard of 'Promise' before.  Did you notice at the bottom of the page that IE does not support it?
RalphAuthor Commented:
Yes.  Fortunately that's not an issue here.
Robert SchuttSoftware EngineerCommented:
Whether you use 'Promise' or not (in this case it seems redundant to me), you have to change the logic in your code (and probably the way you think!). Do not put any code in a function after firing off an asynchronous call. Unless of course it's independent  code that can run in parallel, but when you need the results from the asynchronous call (as seems to be the case in both your pieces of code) you place that code in a callback function which is called when the asynchronous code finishes.

So in the code above, you call the resolve function too soon and the whole mechanism is corrupted. But I think it's easier to explain without using Promise in this case. It's not impossible but not really necessary.

On a previous question you posted the code for the 'clicked_rightmarginTableLink' function being called here, it uses a success function and that's where any code dependent on the response should be (and some already is). You can't return a value from that function though to the call above as it would have to travel back though time and space...

The 'load' call above has the same problem. When you fire the call, it doesn't wait but spawns a separate thread that loads the content while your code continues and shows the alert. The solution is already there: put any code that depends on the result of the load in the function you supply. Basically, move the alert up 1 line.

Fixing the 'clicked_rightmarginTableLink' call is a bit trickier, one option would be to add a callback function to the call itself, like demonstrated in the code below. Now please bear in mind that I did test the code but not to the extent of making all the html & CSS for it. You can see it in action here: http://schutt.nl/ee/Q_28929250/

In the code below I indicated with ### any major changes that I made. Note that I also commented out a number of lines that I deemed unnecessary for testing this. Also, on the test page I call a simple text file instead of a php file but that should not matter.

function loadTables(event)  
{
  event.preventDefault() ;
  var thislink=$(this).attr('href') ;              // The URL of the link clicked
  var destination='#' + $(this).data('target');    // The TARGET of the link clicked
  
  var id_of_rowno='#' + $(this).data('link');      // Add'l info in the <input> element
  var rowno = $(id_of_rowno).val() ;               // Reads the value the the counter
  
  var tablename= $(this).data('link');  // Use this value, ~ RtMgn_tablename
  tablename = tablename.substring(6) ;  // to extract the table whose data must be loaded
  
  // getRandomIntInclusive(min, max)                        // Thinking (now) that I'll populate the form
  var uniq_file_id = getRandomIntInclusive(1, 9999999999) ; // and have to save it uniquely before loading it
  
  // This function will do the AJAX and return the page to load the the form populated 
  // after the SQL activity
  clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id, callback_loadTables) ;

  // ###
  // ### Above I added an argument holding a reference to the function below.
  // ### Ended up doing it like this (function in function) to easily get access to variable 'destination'
  // ###

  function callback_loadTables(new_url)  
  {
    alert("new_url="+new_url) ; 

    // Load the file
    $(destination).load(new_url, function( response, status, xhr )  
    {
      if ( status == "error" ) 
      {
        var msg = "Sorry but there was an error: ";
        alert( msg + xhr.status + " " + xhr.statusText );
      }

      // ###
      // ### I moved the following alert 1 line up, into the result function.
      // ###
      alert("AFTER .load: " + response) ;
    }) ; 
  }
  
} 
// *************************************************************************************************

function clicked_rightmarginTableLink(tablename, rowno, url, uniq_file_id, callback)
{ 
  // Get data from form element to be used for PHP SQL search
  
  
  var php_params = "job=SearchUsing&FormName=form_RightMargin&tablename="+tablename+"&rowno="+rowno ;
  php_params = php_params+"&uniq_file_id="+uniq_file_id+"&url="+url ;
  
  // Would like to use DIV to keep user informed while waiting
  $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  
  // -----------------------------------------------------------------------------------------------
  // Do the magic
  // Change the url to your PHP page
  // I'm using php_params (see above) to pass info to PHP
  // Change the names of your beforeSend, fail, and success JS functions that will respond to
  //   this AJAX call.  (beforeSend line is optional)
  
  var jqXHR = $.ajax({
    url:        'do_sql_query.php' , 
    method:     "GET" ,
    cache:      false ,
    data:       php_params , 
    beforeSend: beforeSend_rightmarginTableLink ,
    fail:       fail_rightmarginTableLink ,
    success:    success_rightmarginTableLink, 
    stop:       stop_rightmarginTableLink
  }) ;
  
  // -----------------------------------------------------------------------------------------------
  function beforeSend_rightmarginTableLink(jqXHR, settings)
  { 
    // Again, I'd like to keep the user updated
    ajax_outstanding++;  
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    $('#AjaxResults').html("") ;
    
    // Clear now irrelevant values
    return ;
  } ;
  
  // -----------------------------------------------------------------------------------------------   
  function fail_rightmarginTableLink(jqXHR, errDesc, exception)
  { 
    // Deliver the bad news
    ajax_outstanding-- ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    alert(errDesc); 
  } ;  
  
  // -----------------------------------------------------------------------------------------------
  function success_rightmarginTableLink(data, status, jqXHR)
  {
    // Update the user
    ajax_outstanding-- ; 
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    
    if (status !== "success")
    {
      alert('Search results not found.') ;
      $('#AjaxResults').html("") ;
    }
    else
    { 
      alert("Before var nrows") ;

      var jsonData = (typeof data === 'string') ? JSON.parse(data) : data ;
      
      var nrows = jsonData.nrows ;
      alert("nrows="+nrows) ;
      if (nrows === 0) 
      {
        $('#AjaxResults').html("There is no data with that ID.") ;
      }
      else 
      {
        alert("Got an asnwer!  "+jsonData.FileToLoad) ;

        // ###
        // ### Instead of 'return'ing the data (into the void), call the callback function
        // ###
        if (typeof callback === 'function')
        {
          callback(jsonData.FileToLoad) ;
        }
        //return JSON.parse(data).FileToLoad ;
        
      }  // EO nrows != 0
    }   // EO success
  };  // EO function success_4ModemSwap_Aircraft((data, status, jqXHR)

  // -----------------------------------------------------------------------------------------------
  function stop_rightmarginTableLink( response, status)
  { 
    // Not sure about this.  May just report when all done
    ajax_outstanding = 0 ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  }

}  // EO AJAX function clicked_rightmarginTableLink()
// 

Open in new window

CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

RalphAuthor Commented:
Hello Robert,

Yes, I do need to think differently.
I'll give your great assistance a try soon and get back.  
I'm still wrapping my head around functions inside functions, and passing any name that could be an object, variable, function, whatever!

Thanks!
RalphAuthor Commented:
I'll put up here what I'm using then explain what's happening.
3 outcomes.

The relevant PHP part:
// Save new file with unique name$result_vector1['values'][1]['date_activation']
            
              file_put_contents($pathToHome."public_html/temp/".$newfile, implode(PHP_EOL, $lines));
              
              // Return to Javascript the file specs to load
              $result_vector1['FileToLoad']=$urlToHome."public_html/temp/".$newfile ;
              sleep(1) ;
              echo json_encode($result_vector1) ;

Open in new window


Most of the JS page:
// ======================================================================================
// This prepares prepares for clicks to the views and tables links on the right side

function RightMargin()  // ready() for right_margin.html
{
  $( 'a.tables' ).on("click",loadTables) ; 
  $( 'a.views' ).on("click",loadViews) ; 
}
// =================================================================================================
// As per set up in function RightMargin(), this responds to table links clicked in the right margin

function loadTables(event)  
{
  event.preventDefault() ;
  
  var thislink=$(this).attr('href') ;              // The URL of the link clicked
  var destination='#' + $(this).data('target');    // The TARGET of the link clicked
  
  var id_of_rowno='#' + $(this).data('link');      // Add'l info in the <input> element
  var rowno = $(id_of_rowno).val() ;               // Reads the value the the counter
  
  var tablename= $(this).data('link');  // Use this value, ~ RtMgn_tablename
  tablename = tablename.substring(6) ;  // to extract the table whose data must be loaded
  
  // getRandomIntInclusive(min, max)                        // Thinking (now) that I'll populate the form
  var uniq_file_id = getRandomIntInclusive(1, 9999999999) ; // and have to save it uniquely before loading it
  
  // This function will do the AJAX and return the page to load the the form populated 
  // after the SQL activity
    
  if (tablename=="Modem")
  { 
    // =================================================================
    
    clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id, callback_loadTables) ; 
    
    function callback_loadTables(jqXHR, new_url) 
    { 
      // Load the file
      alert("Inside callback, jqXHR.status="+jqXHR.status) ;
      
      $(destination).load(new_url, function( response, status, xhr )  
      {
        if ( status == "error" ) 
        { 
          var msg = "Sorry but there was an error: ";
          alert( msg + xhr.status + " " + xhr.statusText ); 
        }  // EO IF
        $('#new_url').append(new_url+"</br>") ;
        alert("You're not waiting?"); 
      }) ;  // EO Callback for load AND load method itself
    }

    
  }  // EO IF "Modem"
  else
  { 
    
    // Load the file  (will be changed from this in the near future, once I get ajax deferred/promised/bleah!)
    $(destination).empty().append(thislink, function( response, status, xhr )  
    {
      if ( status == "error" ) 
      {
        var msg = "Sorry but there was an error: ";
        alert( msg + xhr.status + " " + xhr.statusText );
      }
    $('#new_url').append(thislink+"</br>") ;
    }) ; 
  }  // EO else not "Modem"
}  // EO function loadTables(event)
// =================================================================================================
// As per set up in function RightMargin(), this responds to view links clicked in the right margin

function loadViews(event)
{
  event.preventDefault() ;
  var thislink=$(this).attr('href') ;
  var destination='#' + $(this).data('target');

  $(destination).load(thislink, function( response, status, xhr )  
  {
    if ( status == "error" ) 
    {
      var msg = "Sorry but there was an error: ";
      alert( msg + xhr.status + " " + xhr.statusText );
    }
  }) ; 
} 


// =================================================================================================
// *************************************************************************************************
// RIGHT MARGIN CLICK RESPONDERs BELOW *************************************************************
// 
// *************************************************************************************************

function clicked_rightmarginTableLink(tablename, rowno, url, uniq_file_id, callback_loadTables)
{ 
  // Get data from form element to be used for PHP SQL search
  
  
  var php_params = "job=SearchUsing&FormName=form_RightMargin&tablename="+tablename+"&rowno="+rowno ;
  php_params = php_params+"&uniq_file_id="+uniq_file_id+"&url="+url ;
  
  // Would like to use DIV to keep user informed while waiting
  $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  
  // -----------------------------------------------------------------------------------------------
  // Do the magic
  // Change the url to your PHP page
  // I'm using php_params (see above) to pass info to PHP
  // Change the names of your beforeSend, fail, and done JS functions that will respond to
  //   this AJAX call.  (beforeSend line is optional)
  
  var jqXHR = $.ajax({
    url:        'http://10.139.164.190/Cell_Modems/PHP/do_sql_query.php' , 
    method:     "GET" ,
    cache:      false ,
    data:       php_params , 
    beforeSend: beforeSend_rightmarginTableLink ,
    fail:       fail_rightmarginTableLink ,
    success:    success_rightmarginTableLink, 
    stop:       stop_rightmarginTableLink
  }) ;
  
  // -----------------------------------------------------------------------------------------------
  function beforeSend_rightmarginTableLink(jqXHR, settings)
  { 
    // Again, I'd like to keep the user updated
    ajax_outstanding++;  
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    $('#AjaxResults').html("") ;
    
    // Clear now irrelevant values
    return ;
  } ;
  
  // -----------------------------------------------------------------------------------------------   
  function fail_rightmarginTableLink(jqXHR, errDesc, exception)
  { 
    // Deliver the bad news
    ajax_outstanding-- ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    alert(errDesc); 
  } ;  
  
  // -----------------------------------------------------------------------------------------------
  function success_rightmarginTableLink(data, status, jqXHR)
  {
    // Update the user
    ajax_outstanding-- ; 
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    
    if (status !== "success")
    {
      alert('Search results not found.') ;
      $('#AjaxResults').html("") ;
    }
    else
    { 
      var jsonData = (typeof data === 'string') ? JSON.parse(data) : data ;
      var nrows = jsonData.nrows ;
      
      if (nrows === 0) 
      {
        $('#AjaxResults').html("There is no data with that ID.") ;
      }
      else 
      {
        // alert("Got an asnwer!  "+ jsonData.FileToLoad) ; 
        if (typeof callback_loadTables === 'function')
        {
          callback_loadTables(jqXHR, jsonData.FileToLoad) ;
        }
        
      }  // EO nrows != 0
    }   // EO done
  };  // EO function done_4ModemSwap_Aircraft((data, status, jqXHR)

  // -----------------------------------------------------------------------------------------------
  function stop_rightmarginTableLink( response, status)
  { 
    // Not sure about this.  May just report when all done
    ajax_outstanding = 0 ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  }

}  // EO AJAX function clicked_rightmarginTableLink()

Open in new window


Once in a while all goes well.  
 I get:  "Inside callback, jqXHR.status=200", then the populated modem page loads perfectly.
But then for a reason I can't find, the original View shows up again, overwriting the populated Modem table form.
I've looked and I can't see why that's happening.

The rest of the time, about 75/25, one of two other results.
Either I get:  "Inside callback, jqXHR.status=200", followed by "Sorry but there was an error: 0 error"
which tells me nothing.

Or once in a while I get "Sorry but there was an error: 404 not found"

ALL the time the new_url is put into the header.

I'm wondering if it's still a file arrival thing.  Maybe being there but not readable yet.

Now the strangest thing of all, (in my linear thinking mindset, at least), is if I make the PHP sleep for two seconds, the "Active Ajax searches = 1" loiters for a while, then all alerts are skipped, and I get that darn View loading, with no feedback at all, nothing!

index.html
<!DOCTYPE html>

<html>
  <head>
    <title>index page</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="http://10.139.164.190/Cell_Modems/CSS/PopulateTables.css">
    <script type="text/javascript" src="http://10.139.164.190/Cell_Modems/javascripts/script.js"></script>
    <script type="text/javascript" src="http://10.139.164.190/Cell_Modems/javascripts/TableScripts.js"></script>
    <script type="text/javascript" src="http://10.139.164.190/Cell_Modems/javascripts/ViewScripts.js"></script>
    
    <script type="text/javascript" src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
    
    <script type="text/javascript">
      $(document).ready(Main);
    </script>
    
    
  </head>
  <body>
    
    <?php 
      $path = 'C:/XAMPP/htdocs/Cell_Modems/';
      set_include_path(get_include_path() . PATH_SEPARATOR . $path);
      require 'PHP/core.php'; 
    ?>
    
    <div class="header-container">
      <div class="header"> 
        <div ID="AjaxSearches"></div>
        <div ID="AjaxResults"></div> 
        <div ID="new_url"></div>
        <a href="../PHP/Developer_ParseForm.php">Test Me</a><br>
      </div>
    </div>
    
    <div class="content" >
      
      <div class="left" ID="left_margin"></div>
      
      <div class="center" ID="center_body"> 
  <!--      <div ID="DropBelow"></div>  -->
      </div>
      
      <div class="right" ID="right_margin"></div>
      
    </div>  <!-- CONTENT -->
        
  </body>
</html>

Open in new window



Baffled in Bothell
aka Ralph
Robert SchuttSoftware EngineerCommented:
Well the code seems fine, I have tested it in the simplified environment I created in a subfolder: http://schutt.nl/ee/Q_28929250/new/ Also checked sleep(2) in the php but same result (only an extra second waiting time of course ;-).

The best thing to do is to check the browser console. Should be available by pressing F12 in most browsers:
capture of console (F12 developer tools)
There you will find if there are any errors. I added/changed some alerts to console.log:
// ======================================================================================
// This prepares prepares for clicks to the views and tables links on the right side

function RightMargin()  // ready() for right_margin.html
{
  $( 'a.tables' ).on("click",loadTables) ; 
  $( 'a.views' ).on("click",loadViews) ; 
}
// =================================================================================================
// As per set up in function RightMargin(), this responds to table links clicked in the right margin

function loadTables(event)  
{
  event.preventDefault() ;
  
  var thislink=$(this).attr('href') ;              // The URL of the link clicked
  var destination='#' + $(this).data('target');    // The TARGET of the link clicked
  
  var id_of_rowno='#' + $(this).data('link');      // Add'l info in the <input> element
  var rowno = $(id_of_rowno).val() ;               // Reads the value the the counter
  
  var tablename= $(this).data('link');  // Use this value, ~ RtMgn_tablename
  tablename = tablename.substring(6) ;  // to extract the table whose data must be loaded
  
  // getRandomIntInclusive(min, max)                        // Thinking (now) that I'll populate the form
  var uniq_file_id = getRandomIntInclusive(1, 9999999999) ; // and have to save it uniquely before loading it
  
  // This function will do the AJAX and return the page to load the the form populated 
  // after the SQL activity
    
  if (tablename=="Modem")
  { 
    // =================================================================
    
    clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id, callback_loadTables) ; 
    
    function callback_loadTables(jqXHR, new_url) 
    { 
      // Load the file
      console.log("Inside callback, jqXHR.status="+jqXHR.status) ;
      
      $(destination).load(new_url, function( response, status, xhr )  
      {
        if ( status == "error" ) 
        { 
          var msg = "Sorry but there was an error: ";
          console.log( msg + xhr.status + " " + xhr.statusText ); 
        }  // EO IF
        $('#new_url').append(new_url+"</br>") ;
        console.log("You're not waiting?"); 
      }) ;  // EO Callback for load AND load method itself
    }

    
  }  // EO IF "Modem"
  else
  { 
    
    // Load the file  (will be changed from this in the near future, once I get ajax deferred/promised/bleah!)
    $(destination).empty().append(thislink, function( response, status, xhr )  
    {
      if ( status == "error" ) 
      {
        var msg = "ELSE Sorry but there was an error: ";
        console.log( msg + xhr.status + " " + xhr.statusText );
      }
    $('#new_url').append(thislink+"</br>") ;
    }) ; 
  }  // EO else not "Modem"
}  // EO function loadTables(event)
// =================================================================================================
// As per set up in function RightMargin(), this responds to view links clicked in the right margin

function loadViews(event)
{
  event.preventDefault() ;
  var thislink=$(this).attr('href') ;
  var destination='#' + $(this).data('target');

  $(destination).load(thislink, function( response, status, xhr )  
  {
    if ( status == "error" ) 
    {
      var msg = "Sorry but there was an error: ";
      console.log( msg + xhr.status + " " + xhr.statusText );
    }
  }) ; 
} 


// =================================================================================================
// *************************************************************************************************
// RIGHT MARGIN CLICK RESPONDERs BELOW *************************************************************
// 
// *************************************************************************************************

function clicked_rightmarginTableLink(tablename, rowno, url, uniq_file_id, callback_loadTables)
{ 
  // Get data from form element to be used for PHP SQL search
  
  
  var php_params = "job=SearchUsing&FormName=form_RightMargin&tablename="+tablename+"&rowno="+rowno ;
  php_params = php_params+"&uniq_file_id="+uniq_file_id+"&url="+url ;
  
  // Would like to use DIV to keep user informed while waiting
  $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  
  // -----------------------------------------------------------------------------------------------
  // Do the magic
  // Change the url to your PHP page
  // I'm using php_params (see above) to pass info to PHP
  // Change the names of your beforeSend, fail, and done JS functions that will respond to
  //   this AJAX call.  (beforeSend line is optional)
  
  var jqXHR = $.ajax({
    url:        'http://10.139.164.190/Cell_Modems/PHP/do_sql_query.php' ,
    method:     "GET" ,
    cache:      false ,
    data:       php_params , 
    beforeSend: beforeSend_rightmarginTableLink ,
    fail:       fail_rightmarginTableLink ,
    success:    success_rightmarginTableLink, 
    stop:       stop_rightmarginTableLink
  }) ;
  
  // -----------------------------------------------------------------------------------------------
  function beforeSend_rightmarginTableLink(jqXHR, settings)
  { 
    // Again, I'd like to keep the user updated
    ajax_outstanding++;  
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    $('#AjaxResults').html("") ;
    
    // Clear now irrelevant values
    return ;
  } ;
  
  // -----------------------------------------------------------------------------------------------   
  function fail_rightmarginTableLink(jqXHR, errDesc, exception)
  { 
    // Deliver the bad news
    ajax_outstanding-- ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    alert(errDesc); 
  } ;  
  
  // -----------------------------------------------------------------------------------------------
  function success_rightmarginTableLink(data, status, jqXHR)
  {
    // Update the user
    ajax_outstanding-- ; 
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
    
    if (status !== "success")
    {
      alert('Search results not found.') ;
      $('#AjaxResults').html("") ;
    }
    else
    { 
      var jsonData = (typeof data === 'string') ? JSON.parse(data) : data ;
	  console.log('jsonData:', jsonData);
      var nrows = jsonData.nrows ;
      
      if (nrows === 0) 
      {
        $('#AjaxResults').html("There is no data with that ID.") ;
      }
      else 
      {
        // alert("Got an asnwer!  "+ jsonData.FileToLoad) ; 
        if (typeof callback_loadTables === 'function')
        {
          callback_loadTables(jqXHR, jsonData.FileToLoad) ;
        }
        
      }  // EO nrows != 0
    }   // EO done
  };  // EO function done_4ModemSwap_Aircraft((data, status, jqXHR)

  // -----------------------------------------------------------------------------------------------
  function stop_rightmarginTableLink( response, status)
  { 
    // Not sure about this.  May just report when all done
    ajax_outstanding = 0 ;
    $('#AjaxSearches').html(ajax_outstanding+" Active Searches") ;
  }

}  // EO AJAX function clicked_rightmarginTableLink()

Open in new window


I have a couple of questions:
- are those full paths necessary? if you ever need to change the server you may regret those. Also, if they differ from the current URL (localhost?) they may cause an error.
- have you double-checked that the file exists in the temp directory when you get a 404 error?
- are you sure that the correct code is executed (tablename=="Modem")? in the code above I changed the error so it's clear when it comes from there (but I also changed the data-link on the only link I have).

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
RalphAuthor Commented:
I'm sparing you all that I wrote before b/c it was with the netbeans Connector and a diff jquery lib.

-- -- --

All right, after lunch and I've turned off netbeans' Connector.
...and, slightly different behavior.  It loads correctly about 1/2 the time if I'm `inspecting` with a 1-second delay in PHP, (with 2 secs it works almost reliably!), otherwise with 0 delay it does not load.

I also switched to jquery-2.2.1.js, not minimized, and I can see the point where I was getting a JS-library error.  It was in the other tables' load, so I took off .empty().html() and just put .load there too.  No error there!  That'll learn me to not try everything I see in forums.
-- --

Interesting, when I do get the modem_table_xxxx.html to load, I get:
Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check https://xhr.spec.whatwg.org/.

The .js file is there, and that ready function is simply:
// *******************************************************************
function Modem_Table(){
  $(':text:first').focus();
  $(document).keydown(function (e){ toggle_key } ) ; 
}
and
// *************************************************************************************************

function toggle_key(e)
{ 
  if (e.altKey)
  { if ($(".Button_AddNote").val() == "Add Note")
    {
      $(".Button_AddNote").val('Add ToDo');  $(".Button_AddNote").css('color','#FF00FF') ;
      $('#addnote_4ModemSwap_ModemOff').val('Add ToDo');  $('#addnote_4ModemSwap_ModemOff').css('color','#FF00FF') ;
      $('#addnote_4ModemSwap_ModemOn').val('Add ToDo');   $('#addnote_4ModemSwap_ModemOn').css('color','#FF00FF') ;
    }
    else
    {
      $(".Button_AddNote").val('Add Note');  $(".Button_AddNote").css('color','#0000AA') ;
     $('#addnote_4ModemSwap_ModemOff').val('Add Note');  $('#addnote_4ModemSwap_ModemOff').css('color','#0000AA') ;
      $('#addnote_4ModemSwap_ModemOn').val('Add Note');   $('#addnote_4ModemSwap_ModemOn').css('color','#0000AA') ;
    } 
  }
}

Open in new window


For a while there if I kept clicking links to tables to load, though only Modem is 'accessorized', eventually, from top down, including that View, all the links would stop responding.  If I kept clicking the ones that did, eventually they too would stop responding.
Links on the left worked, but not the right until I reloaded the page.
A 'leak' in my code somewhere.
And for some reason it's not happening now...  (Worse?)

Another oddity here:
if (tablename=="Modem")
  { 
    // =================================================================
    
    clicked_rightmarginTableLink(tablename, rowno, thislink, uniq_file_id, callback_loadTables) ; 
    
    function callback_loadTables(jqXHR, new_url) 
    { 
      // Load the file
      console.log("Inside callback, jqXHR.status="+jqXHR.status+", new_url="+new_url) ; 
      did_we_enter=0 ;
      $(destination).load(new_url, function( response, status, xhr )  
      {
        if ( status == "error" ) 
        { 
          var msg = "Sorry but there was an error: ";
          alert( msg + xhr.status + " " + xhr.statusText );  
        }  // EO IF
        did_we_enter=1 ; 
      }) ;  // EO Callback for load AND load method itself
      alert("did_we_enter="+did_we_enter) ;
      if (did_we_enter === 0) { $('#AjaxResults').html("Failed to load. PHP to JS handoff error.") ;}
    } 
  }  // EO IF "Modem"

Open in new window

Apparently I don't follow things as well as I thought I did.
did_we_enter=1 does not happen even when the page loads good.
Is there some way to inform the user WTHeck's up when doesn't error but also doesn't load?
AND, I love this, (sic), I'm getting the alert(did we enter) BEFORE alert(Sorry there was an error).
Aghhhhhhh!!!

Thank you Robert,
Ralph
Robert SchuttSoftware EngineerCommented:
I said earlier: do not put code after an asynchronous call if it depends on the outcome of that call. In your last piece of code you're doing exactly that: lines 21 and 22 are being executed directly after the load is executed. Lines 14-19 which you need to execute before that, are actually executed at a later time, after the load completes. Any code you need to execute after the load, should go inside that callback function.

Yes, making it a synchronous call solves this 'problem' but is NOT recommended and as the error message tells you, will be or is already deprecated. Don't use it as it is not necessary and might create a situation where your browser will hang completely.

I must admit, the whole story before that last bit of code is not making sense to me, the code is unrelated, the description of what you're doing is unclear. I'm gonna ignore that for now.

I can't make it simpler: put code that needs to be run after the load inside the response function. Only then will it be executed with the correct result data available. If you know a link will call code that's not inside the correct part of the 'if ... modem' then stop clicking it or remove the bad part of the code.

The code I posted works, you can check that on my site. If you need changes to it, ask specific questions because trying to add code in the same way as you did before will just not work.
RalphAuthor Commented:
TWO Asynchronous events.
The 21-22 alert not after but before the 2nd, and after the 1st.
Got it.

Yes, the write up makes as much sense as the bizarre behaviour that was happening.

Thanks Robert, I'm on my way again.

Ralph
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
jQuery

From novice to tech pro — start learning today.