javascript - AJAX calls sequenced by JS Promises appear to be running in the proper order, but the output from the database suggests otherwise -


i have 2 files i'm working here. query.php script wrote handle mysql queries particular website. query_test.js series of ajax calls test query.php. query_test.js, see below, uses promises sequence 1 test after another, have made tests dependent upon 1 another. writing console, ajax calls appear finishing in correct order. problem output inconsistent , output of individual tests not reflecting results of tests before them. since individual tests seem work fine, believe sequencing issue. can't figure out why , how happening.

for clarity, tests follows:

  • test 1: retrieve entire table , display
  • test 2: add new row, then retrieve , display table again
  • test 3: select just-added row, display results
  • test 4: update just-added row, retrieve , display table
  • test 5: remove just-added row, retrieve , display table

in example output below, notice table retrieved after test 2 not reflect row added , test 3's query returns nothing. isn't until test 4 previously-added row seems show up. each execution yields different output; normal, , other times wrong above. console output always shows each call in order it's supposed be. makes me think in backend going wrong, i'm clueless is.

query.php

<?php /**  purpose of script query database in number of ways.  script should called via ajax. see below supported actions ,  required parameters each.   -------- actions ($_post["action"])-----------  1. get_table: retrieve entire table     - parameters:          "table_name": [string] name of table      - returns: [json] entire table  2. update_table: update row in table     - parameters:          "table_name": [string] name of table         "queries": [array] list of queries, so: <column>[<relational_operator]<value> find rows update         "values": [array] key=>value pairs each column updated.  3. select_table: select specified columns specified rows     - parameters:         "table_name": [string] name of table         "queries": [array] list of queries, so: <column>[<relational_operator]<value>         "columns": (optional) [array] list of column names returned. default value '*', or columns     - returns: [json] rows returned query  4. add_row: add row table     - parameters:         "table_name": [string] name of table         "values": [array] key=>value pairs of columns names , corresponding values new row  5. remove_row: remove row or rows table     - parameters:         "table_name": [string] name of table         "queries": [array] list of queries, so: <column>[<relational_operator]<value>  **/  // constants // actions define("get_table", 100);  define("update_table", 101); define("select_table", 102);  define("add_row", 103); define("remove_row", 104);  $server = "localhost"; $username = "root"; $password = "password"; $db_name = "test";  $conn = new mysqli($server, $username, $password, $db_name); if ($conn->connect_error) die("connection failed: " . $conn->connect_error);  // action must set checkpost("action") or die("error: post variable 'action' must setand not empty."); $action = $_post["action"];  // table name must given actions checkpost("table_name") or die("error: post variable 'table_name' must set , not empty."); $table = $_post["table_name"];  // generic error message $param_err = "error: ensure required params set , not empty.";  // see action needs done switch ($action) {     case get_table:         // run query         $q = "select * $table";         $result = $conn->query($q);         $result or die("query '" . $q . "' failed: " . $conn->error);         if ($result->num_rows > 0) {             $output = array();             while ($row = $result->fetch_assoc()) {                 $output[] = $row;             }             echo json_encode($output);         }         break;     case update_table:         // check additional required params         (checkpost("values") && checkpost("queries"))              or die($param_err);         $values = $_post["values"];         $queries = $_post["queries"];          $q = "update $table";          // add values set query         $q .= " set ";         addquotestostrings($values);         additemstoquery($q, $values, true);          // add clause @ end of query         $q .= " ";         additemstoquery($q, $queries, false);          // ready send off query db , report success or failure         $conn->query($q) or die("query '" . $q . "' failed: " . $conn->error);         echo "successfully updated " . $conn->affected_rows . " rows.";          break;     case select_table:         // check additional required params         checkpost("queries") or die($param_err);         $queries = $_post["queries"];          $q = "select ";          // add columns if specified         if (checkpost("columns")) {             $columns = $_post["columns"];             additemstoquery($q, $columns, false);         }         else $q .= "* "; // no columns specified. select          // add table name         $q .= "from $table ";          // add queries         $q .= "where ";         additemstoquery($q, $queries, false);          // now, send off query         $result = $conn->query($q);         $result or die("query '" . $q . "' failed: " . $conn->error);         if ($result->num_rows > 0) {             $output = array();             while ($row = $result->fetch_assoc()) {                 $output[] = $row;             }             echo json_encode($output);         }          break;     case add_row:         // check post var "values"         checkpost("values") or die($param_err);         $values = $_post["values"];          $q = "insert $table";          // first, add column names         $q .= " (";         additemstoquery($q, array_keys($values), false);         $q .= ") ";          // add values         $q .= "values (";         addquotestostrings($values);         additemstoquery($q, $values, false);         $q .= ")";          // run query         $conn->query($q) or die("query '" . $q . "' failed: " . $conn->error);         echo "query successful.";          break;     case remove_row:         // check queries         checkpost("queries") or die($param_err);         $queries = $_post["queries"];          $q = "delete $table";          // add queries         $q .= " ";          additemstoquery($q, $queries, false);          // run query         $conn->query($q) or die("query '" . $q . "' failed: " . $conn->error);         echo "query affected " . $conn->affected_rows . " rows.";          break;     default:         die("error: post variable 'action' has unknown value."); }  /**     adds items array sql query string     assumes space present before last keyword of existing query.      @param  string  &$q     reference sql query string     @param  array   $items  array containing strings need added query in list format (e.g. item1,item2,item3)     $param  boolean $pairs  boolean indicated whether items key=>value pairs or not **/ function additemstoquery(&$q, $items, $pairs) {     $first = true;     foreach ($items $name => $item) {         if (!$first) $q .= ", ";         else $first = false;         $q .= $pairs ? $name . "=" . $item  : $item;     } }  /**     adds single quotes each string in array of items purpose of being added mysql query      @param  array   $values reference array of items **/ function addquotestostrings(&$values) {     foreach ($values &$value) {         if (strcmp(gettype($value), "string") == 0) $value = "'" . $value . "'";      }     unset($value); }  /**     simple helper function check if post var set , not empty      @param  string  $name   name of post variable **/ function checkpost($name) {     return isset($_post[$name]) && !empty($_post[$name]); } ?> 


query_test.js

    // script series of ajax calls test query.php  const get_table = 100; const update_table = 101; const select_table = 102; const add_row = 103; const remove_row = 104;  /**     runs ajax request query.php , displays result      @param  {jquery}    div             jquery object div place results     @param  {array}     params          assoc. array of post variables ajax call     @param  {boolean}   displayastable  determines result displayed table or      @return {promise}   promise object **/ function runtest(div, params, displayastable) {     return promise.resolve($.post("../php/query.php", params, function(data) {         // display result         if (displayastable) {             let tabledata = json.parse(data);             let table = $('<table></table>');             (let rowkey in tabledata) {                 let row = $('<tr></tr>');                 (let colkey in tabledata[rowkey]) {                     let col = $('<td></td>');                     col.html(tabledata[rowkey][colkey]);                     row.append(col);                 }                 table.append(row);             }             div.append(table);         }         else div.append($('<p>' + data + '</p>'));     })); }  var num = 0; // temporary function test if promise order holds function logorder(test) {     num++;     console.log(test + " finished: " + num); }  // ----------- test 1: retrieve table ---------------- let div = $('<div></div><br>'); let header = $('<h2>test 1: retrieve table</h2>'); div.append(header); $('body').append(div); let params = {action: get_table, table_name: "projects"}; var promise = runtest(div, params, true);  // ------------ test 2: add row ---------------------- promise = promise.then(function(value) {     logorder("test 1");      let div = $('<div></div><br>');     let header = $('<h2>test 2: add row</h2>');     div.append(header);     $('body').append(div);     let values = {title: "test_proj", pic: "none.jpg", brief: "testing", description: "this test"};     let params = {action: add_row, values: values, table_name: "projects"};     runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure row has been added promise = promise.then(function(value) {     logorder("test 2");      let div = $('<div></div><br>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 3: select table ------------------- promise = promise.then(function(value) {     logorder("test 2 check");      let div = $('<div></div><br>');     let header = $('<h2>test 3: select table</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let params = {action: select_table, table_name: "projects", queries: queries};     runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 4: update table ------------------- promise = promise.then(function(value) {     logorder("test 3");      let div = $('<div></div><br>');     let header = $('<h2>test 4: update table</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let values = {brief: "this updated", description: "this updated"};     let params = {action: update_table, table_name: "projects", queries: queries, values: values};     runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure table has been updated promise = promise.then(function(value) {     logorder("test 4");      let div = $('<div></div><br>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 5: remove row(s) ------------------ promise = promise.then(function(value) {     logorder("test 4 check");      let div = $('<div></div><br>');     let header = $('<h2>test 5: remove row(s)</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let params = {action: remove_row, table_name: "projects", queries: queries};     runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure row has been removed promise = promise.then(function(value) {     logorder("test 5");      let div = $('<div></div>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     runtest(div, params, true); }, function(error) {     alert(error); }).then(function(value) {     logorder("test 5 check"); }, function(error) {     alert(error); }); 


example output:

test 1: retrieve table  11  placeholder none.jpg    placeholder placeholder description  test 2: add row  query successful.  11  placeholder none.jpg    placeholder placeholder description  test 3: select table   test 4: update table  updated 1 rows.  11  placeholder none.jpg    placeholder placeholder description 17  test_proj   none.jpg    updated    updated  test 5: remove row(s)  query affected 1 rows.  11  placeholder none.jpg    placeholder placeholder description 

i figured out doing wrong after looking @ this.

i made changes suggested @darkknight, wasn't issue, or @ least wasn't issue.

it turns out needed return promise inside every promise.then() success function. originally, wasn't doing this. after first test, each subsequent test starting query calling next then() instead of waiting result since nothing being done new promise.

here new query_test.js:

// script series of ajax calls test query.php  const get_table = 100; const update_table = 101; const select_table = 102; const add_row = 103; const remove_row = 104;  /**     runs ajax request query.php , displays result      @param  {jquery}    div             jquery object div place results     @param  {array}     params          assoc. array of post variables ajax call     @param  {boolean}   displayastable  determines result displayed table or      @return {promise}   promise object **/ function runtest(div, params, displayastable) {     return new promise(function(resolve, reject) {         $.post("../php/query.php", params, function(data) {             // display result             if (displayastable) {                 let tabledata = json.parse(data);                 let table = $('<table></table>');                 (let rowkey in tabledata) {                     let row = $('<tr></tr>');                     (let colkey in tabledata[rowkey]) {                         let col = $('<td></td>');                         col.html(tabledata[rowkey][colkey]);                         row.append(col);                     }                     table.append(row);                 }                 div.append(table);             }             else div.append($('<p>' + data + '</p>'));         }).then(resolve, reject)     }); }  var num = 0; // temporary function test if promise order holds function logorder(test) {     num++;     console.log(test + " finished: " + num); }  var promise = promise.resolve();  // ----------- test 1: retrieve table ---------------- promise = promise.then(function(value) {     let div = $('<div></div><br>');     let header = $('<h2>test 1: retrieve table</h2>');     div.append(header);     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     return runtest(div, params, true); }, function(error) {     alert(error); });  // ------------ test 2: add row ---------------------- promise = promise.then(function(value) {     logorder("test 1");      let div = $('<div></div><br>');     let header = $('<h2>test 2: add row</h2>');     div.append(header);     $('body').append(div);     let values = {title: "test_proj", pic: "none.jpg", brief: "testing", description: "this test"};     let params = {action: add_row, values: values, table_name: "projects"};     return runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure row has been added promise = promise.then(function(value) {     logorder("test 2");      let div = $('<div></div><br>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     return runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 3: select table ------------------- promise = promise.then(function(value) {     logorder("test 2 check");      let div = $('<div></div><br>');     let header = $('<h2>test 3: select table</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let params = {action: select_table, table_name: "projects", queries: queries};     return runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 4: update table ------------------- promise = promise.then(function(value) {     logorder("test 3");      let div = $('<div></div><br>');     let header = $('<h2>test 4: update table</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let values = {brief: "this updated", description: "this updated"};     let params = {action: update_table, table_name: "projects", queries: queries, values: values};     return runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure table has been updated promise = promise.then(function(value) {     logorder("test 4");      let div = $('<div></div><br>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     return runtest(div, params, true); }, function(error) {     alert(error); });  // -------------- test 5: remove row(s) ------------------ promise = promise.then(function(value) {     logorder("test 4 check");      let div = $('<div></div><br>');     let header = $('<h2>test 5: remove row(s)</h2>');     div.append(header);     $('body').append(div);     let queries = ["title='test_proj'"];     let params = {action: remove_row, table_name: "projects", queries: queries};     return runtest(div, params, false); }, function(error) {     alert(error); });  // table ensure row has been removed promise = promise.then(function(value) {     logorder("test 5");      let div = $('<div></div>');     $('body').append(div);     let params = {action: get_table, table_name: "projects"};     return runtest(div, params, true); }, function(error) {     alert(error); });  promise.then(function(value) {     logorder("test 5 check"); }, function(error) {     alert(error); }); 

Comments

Popular posts from this blog

javascript - Thinglink image not visible until browser resize -

firebird - Error "invalid transaction handle (expecting explicit transaction start)" executing script from Delphi -

mongodb - How to keep track of users making Stripe Payments -