Make AJAX Callbacks work within an iterator - php

Why isn't this working? Only the success call for first response is working.
for(i = 1; i <= 6; i++) {
$.ajax({
url : 'runTest.php',
type : 'post',
data : "testNumber="+i+"&url=" + testUrl,
dataType : 'json',
success : function(data) {
var row = $('<tr />');
$('<td />').text(data.testName).appendTo(row);
$('<td />').text(data.testSeverity).appendTo(row);
$('<td />').text(data.testResult).appendTo(row);
$('<td />').text(data.testResultDetail).appendTo(row);
$('<td />').text(data.testDescription).appendTo(row);
$('table#results tbody').append(row);
}
});
}

There may be a problem on the server side. You're triggering the same PHP script six times at once; perhaps the database (or whatever) is locking on the first request and the other five return errors which you aren't checking for. In that case, you need to include some kind of while...sleep loop inside the PHP that waits until the database is available.
Here's what I did for a similar problem, when I was using a PHP script to retrive data from Google Maps and was running into request limits. But the idea is simple enough, and you should be able to modify it for your own needs:
$params = http_build_query($_GET);
$url = "http://maps.googleapis.com/maps/api/directions/json?sensor=false&" . $params;
$json = file_get_contents($url);
$status = json_decode($json)->status;
// check for over_query_limit status
while ($status=="OVER_QUERY_LIMIT") {
sleep(0.2); // seconds
$json = file_get_contents($url);
$status = json_decode($json)->status;
}

Related

Running out of HTTP requests with a Ajax function on my server

I don't know so much about servers and HTTP requests limits, in my case I have a Linux Deluxe hosting on GoDaddy, which runs pretty smoothly, but now I would need to understand why my website goes unreachable (ERR_CONNECTION_CLOSED) after launching the following code 2-3 times (the first time it goes fine, the issue comes when I refresh the page 1-2 other times):
My ajax call:
function XSGetPointer(id, tableName) {
var pointer;
var ok = false;
$.ajax({
url : TABLES_PATH + 'm-query.php?',
type: 'POST',
data: 'tableName=' + tableName,
async: false,
success: function(data) {
var results = JSON.parse(data);
for(var i=0; i<results.length; i++) {
if (results[i]['ID_id'] == id ) {
pointer = results[i];
ok = true;
}
if (i == results.length-1 && !ok) {
pointer = null;
}
}
// error
}, error: function(e) {
console.log('XSCurrentUser -> Something went wrong: ' + e.message);
}});
return pointer;
}
PHP for loop where that JS script gets called:
for(var i=0; i<objectsArray.length; i++){
var userPointer = XSGetPointer(objectsArray[i]['PO_userPointer_Users'], 'Users');
$('#queryData').append(
'<p>'
+userPointer['ST_username']+
'<br></p>'
);
}// ./ For • Show results
The for loop above iterates through 57 items (the objectsArray's length). The m-query.php script simply gets all data from a JSON file, like this:
// Get JSON data
$data = file_get_contents($tableName. '.json');
$data_array = json_decode($data, true);
echo json_encode(array_values($data_array), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
The support from GoDaddy told me to get a VPS server, but I couldn't understand the real cause of my issue, I suppose is something related to the many HTTP requests I send in the same page, as shown here:
As you can see, my ajax call stops after a few calls, it doesn't get to 57, and the Chrome Console shows:
jquery-3.4.1.min.js:2 POST https://example.com/m-query.php? net::ERR_CONNECTION_CLOSED
I just wanted to know if switching to a VPS server may fix this issue, or if my ajax query is just totally wrong since it's also async: false (I cannot make it true, because it doesn't get JSON data then).
I’ve solved the issue by simply moving my php files into an AWS Lightsail instance

Get url variable from AJAX in PHP

I've looked at a couple of related topics here on Stackoverflow such as this answer, but I can't seem to get this one correct – it could be something particular in my code, but I don't think that should be the case, thus I'm seeking your advice.
My goal is to pass index.php?key=123testID through the client.js script below to my update-check.php in order to long-poll the txt file with the corresponding name (in this example 123testID.txt). If there's an other way for update-checker to grab the variable, that is also acceptable.
I currently have working functionality for long-polling the .txt data – I simply want to add the functionality to dynamically load the txt file with the same name as the URL variable.
At the moment my code looks like this:
client.js
function getContent(timestamp)
{
var queryString = {'timestamp' : timestamp};
$.ajax(
{
type: 'GET',
url: 'update-check.php',
data: queryString,
success: function(data){
// put result data into "obj"
var obj = jQuery.parseJSON(data);
// put the data_from_file into #response
$('#response').html(obj.data_from_file);
// call the function again, this time with the timestamp we just got from server.php
getContent(obj.timestamp);
}
}
);
}
// initialize jQuery
$(function() {
getContent();
});
update-check.php
<?php
// set php runtime to unlimited
set_time_limit(0);
// how can I load a variable insead of a static txt file?
$data_source_file = "stories/123testID.txt";
// main loop
while (true) {
// if ajax request has send a timestamp, then $last_ajax_call = timestamp, else $last_ajax_call = null
$last_ajax_call = isset($_GET['timestamp']) ? (int)$_GET['timestamp'] : null;
clearstatcache();
// get timestamp of when file has been changed the last time
$last_change_in_data_file = filemtime($data_source_file);
if ($last_ajax_call == null || $last_change_in_data_file > $last_ajax_call) {
$data = file_get_contents($data_source_file);
$result = array(
'data_from_file' => $data,
'timestamp' => $last_change_in_data_file
);
// encode to JSON, render the result (for AJAX)
$json = json_encode($result);
echo $json;
// leave this loop step
break;
} else {
sleep( 1 );
continue;
}}?>

Ajax response while remote php runs

i want to get data echoed in the remote php after i sent the main request and before i get the complete response.
the intent is to show "i am almost there - 5 items remaining" or similer...
This is my current js script:
function getdetails(){
$("div#urltable").fadeOut('fast');
$("div#ajaxLoading").fadeIn('fast');
var checkurl = $('input#remoteurl').attr('value');
if($("#checkBrokenLinks").prop('checked') == true){
var checkonline = 'check';
}
else {
var checkonline = 'skip';
}
$.ajax({
type: "POST",
url: "ajax-outlink_checker.php",
data: {checkurl:checkurl, checkonline: checkonline}
}).always(function(data) {
var $response = $(data);
var whileRuningCount = $response.filter('#whileRuningCount').html();
$("div#whileRuningCount").fadeOut('fast');
$("div#whileRuningCount").fadeIn('fast');
$("div#whileRuningCount").html(whileRuningCount);
}).done(function(result) {
var $response=$(result);
var urltable = $response.filter('#urltable').html();
var whileRuningCount = $response.filter('#whileRuningCount').html();
$("div#ajaxLoading").fadeOut('fast');
$("div#urltable").fadeIn('fast');
$("div#urltable").html(urltable);
});
}
As you can see
i added .always() trying to grab the echo's the run in the php file.
but... i guess i missunderstand how to make it work and if .always
is even the way to go about it.
Any help would be most apreaciated.
Best regards, Sagive.
You'll need to make 2 separate ajax calls. 1 for the initial request, and then a second one repeated as often as needed to check for status updates. The action responder will need to update some variable for the status responder to check. How you communicate the status to the other responder is up to you. One method is to simply use a file. Your action responder will call handleaction() while the status responder will only call statuscheck():
<?php
function handleaction()
{
$actions_left = 0;
while ($actions_left > 0)
{
perform_action();
status_update(--$actions_left);
}
}
function status_update($remaining)
{
$filename = "/" . session_id() . "_action_status.txt";
$fh = fopen($filename, "w");
fputs($fh, $remaining);
fclose($fh);
}
function statuscheck()
{
$filename = "/" . session_id() . "_action_status.txt";
echo #file_get_contents($filename); // js treats empty response as 0.
}
?>
.always() is not for that. It just means that whether the request was success/done() or fail() run what is in that snippet.
If you are trying to show an "almost there.." message, a better way would be to have another async call to the server which polls every N seconds, looks at some data state in the server, (a flag maybe?) and based on that shows a message in the front end..

jqGrid after Delete error

Here is the example delete options I'm using using in a jqGrid. It works just fine and my serverside scripts are working perfectly. The records get deleted, but there is something that goes wrong after the response from the server is received.
// Del Options
{
mtype: "POST",
modal: true,
url: "/internal/backupmanagement/backupmanager/deleteMySQLDB",
reloadAfterSubmit: false,
onclickSubmit: function () {
var post = $("#grid_" + o.id).jqGrid("getGridParam", "postData");
var server = post.serverID;
$.openDialog("load", "Deleting old database entry. Please wait...");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
var row = $("#grid_" + o.id).jqGrid("getRowData", selrow);
console.log("about to return", row, server);
return {
id: row.recid,
database: row.database,
server: server
};
},
afterSubmit: function (response, postdata) {
response = eval("(" + response.responseText + ")");
console.log(response);
return [true, "success"];
},
afterComplete: function (response, postdata, formid) {
response = eval("(" + response.responseText + ")");
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
$("#grid_" + o.id).jqGrid("delRowData", selrow);
if (response.error == 0) {
$.openDialog("info", "Successfully deleted " + postdata.database + ".");
} else {
$.openDialog("info", "And error occured - " + response.msg + ".");
}
}
}
I get the following error before the afterComplete event is fired in the grid :
Uncaught TypeError: Object [object Array] has no method 'split'
So it seems something is being returned as an object when it was expecting a string. I'm not sure if my response from the server is formatted correctly and I wasn't able to find any expected response in the documentation either.
* UPDATE *
Server-side code as requested. I've just included the controller function that interacts with the jqGrid, the rest is working and happening further on in the application.
function deleteMySQLDB()
{
if (IS_AJAX) {
if (($this->Application->deleteMySQLDBData(
$_POST["id"],
$_POST["database"],
$_POST["server"]
)) === false) {
echo json_encode(
array(
"error" => 1,
"msg" => "Failed Deleting record from database: "
.$this->Application->error
)
);
return false;
}
echo json_encode(
array(
"error" => 0,
"msg" => "success"
)
);
return true;
} else {
header("Location: /");
}
}
I hope this helps to see what I'm currently returning to the grid.
* UPDATE *
What I have done is changed the source in the jqGrid plugin to include a toString() on the value before preforming the split.
On line 331 of jquery.jqGrid.min.4.3.1 :
var A=[];A=H.split(",");
Changed to :
var A=[];A=H.toString().split(",");
It seemed like a harmless change in the grand scheme of things and avoids arrays to be attempted to get split. Thanks a lot for the help guys. You certainly pointed me in the right place to start looking, Oleg!
Let's suppose that the origin of the described error is the code of your afterComplete callback. I think that you are using it in a wrong way. I don't understand some parts of the code, the part (testing of response.error) should be moved in afterSubmit.
The main problem will be clear if you examine the lines of code where afterComplete callback will be called. It will be executed inside of setTimeout with 0.5 sec delay. At the time new data in the grid can be loaded (or could be loading). So it would be wrong to use methods like delRowData and the value of selrow could be changed now.
I would strictly recommend you additionally don't use eval function. Instead of the line
response = eval("(" + response.responseText + ")");
it will be correct to use
response = $.parseJSON(response.responseText);
The code of onclickSubmit callback could be improved if you would use the fact that this inside of the callback (like the most other callbacks o jqGrid) are initialized to DOM element of the grid. So to get selrow option of the grid you can use
var selrow = $(this).jqGrid("getGridParam", "selrow");
instead of
var selrow = $("#grid_" + o.id).jqGrid("getGridParam", "selrow");
Another fact is onclickSubmit will be called by jqGrid with two parameters: options and postdata. The parameter postdata is rowid if you use don't use multiselect: true. In case of usage of multiselect: true the value of postdata parameter of the callback can be comma separated list of rowids of the rows which will be deleted. So the usage of postdata is better as the usage of selrow.
I"m making a good guess since you didn't include your server side code.
On the server you can return something like:
return Json(new { success = false, showMessage = true, message = "Error - You can't have a negative value", title = "Error" });
Then on your client you can have something to display a message (in this example if there was an error)
afterComplete: function (response) {
var DialogVars = $.parseJSON(response.responseText); //parse the string that was returned in responseText into an object
if (!DialogVars.success || DialogVars.showMessage) {
showDialog($('#Dialog'), DialogVars.message, DialogVars.title);
}
} //afterComplete

Retrieving Data with Jquery, AJAX, and PHP from a MySQL Database

I am trying to figure out how to retrieve data from a MySQL database using an AJAX call to a PHP page. I have been following this tutorial
http://www.ryancoughlin.com/2008/11/04/use-jquery-to-submit-form/
But i cant figure out how to get it to send back json data so that i can read it.
Right now I have something like this:
$('h1').click(function() {
$.ajax({
type:"POST",
url: "ajax.php",
data: "code="+ code,
datatype: "xml",
success: function() {
$(xml).find('site').each(function(){
//do something
});
});
});
My PHP i guess will be something like this
<?php
include ("../../inc/config.inc.php");
// CLIENT INFORMATION
$code = htmlspecialchars(trim($_POST['lname']));
$addClient = "select * from news where code=$code";
mysql_query($addClient) or die(mysql_error());
?>
This tutorial only shows how to insert data into a table but i need to read data. Can anyone point me in a good direction?
Thanks,
Craig
First of all I would highly recommend to use a JS object for the data variable in ajax requests. This will make your life a lot simpler when you will have a lot of data. For example:
$('h1').click(function() {
$.ajax({
type:"POST",
url: "ajax.php",
data: { "code": code },
datatype: "xml",
success: function() {
$(xml).find('site').each(function(){
//do something
});
});
});
As for getting information from the server, first you will have to make a PHP script to pull out the data from the db. If you are suppose to get a lot of information from the server, then in addition you might want to serialize your data in either XML or JSON (I would recomment JSON).
In your example, I will assume your db table is very small and simple. The available columns are id, code, and description. If you want to pull all the news descriptions for a specific code your PHP might look like this. (I haven't done any PHP in a while so syntax might be wrong)
// create data-structure to handle the db info
// this will also make your code more maintainable
// since OOP is, well just a good practice
class NewsDB {
private $id = null;
var $code = null;
var $description = null;
function setID($id) {
$this->id = $id;
}
function setCode($code) {
$this->code = $code;
}
function setDescription($desc) {
$this->description = $desc;
}
}
// now you want to get all the info from the db
$data_array = array(); // will store the array of the results
$data = null; // temporary var to store info to
// make sure to make this line MUCH more secure since this can allow SQL attacks
$code = htmlspecialchars(trim($_POST['lname']));
// query
$sql = "select * from news where code=$code";
$query = mysql_query(mysql_real_escape_string($sql)) or reportSQLerror($sql);
// get the data
while ($result = mysql_fetch_assoc($query)) {
$data = new NewsDB();
$data.setID($result['id']);
$data.setCode($result['code']);
$data.setDescription($result['description']);
// append data to the array
array_push($data_array, $data);
}
// at this point you got all the data into an array
// so you can return this to the client (in ajax request)
header('Content-type: application/json');
echo json_encode($data_array);
The sample output:
[
{ "code": 5, "description": "desc of 5" },
{ "code": 6, "description": "desc of 6" },
...
]
So at this stage you will have a PHP script which returns data in JSON. Also lets assume the url to this PHP script is foo.php.
Then you can simply get a response from the server by:
$('h1').click(function() {
$.ajax({
type:"POST",
url: "foo.php",
datatype: "json",
success: function(data, textStatus, xhr) {
data = JSON.parse(xhr.responseText);
// do something with data
for (var i = 0, len = data.length; i < len; i++) {
var code = data[i].code;
var desc = data[i].description;
// do something
}
});
});
That's all.
It's nothing different. Just do your stuff for fetching data in ajax.php as usually we do. and send response in your container on page.
like explained here :
http://openenergymonitor.org/emon/node/107
http://www.electrictoolbox.com/json-data-jquery-php-mysql/

Categories