Ajax sometimes fails to parse the large JSON response - php

I am calling a PHP service with below ajax code :
jQuery.ajax({
url: 'index.php?option=com_sheet&task=getReportsData',
timeout: 300000,
dataType: "json",
type: "GET",
data: {
'project': projectsStr,
'startweek': startweek,
'endweek': endweek
}
}).done(function(response) {
if (response.success && response.data) {
var projectData = response.data;
if (projectData.projectReportData.length > 0) {
loadDataTable(response.data);
} else {
jQuery('#projectReportData').html("<br/><h2>No Matching Results</h2>");
}
}
}).fail(function(jqXHR, textStatus) {
jQuery(".overlay")[0].style.display = '';
if (textStatus === 'timeout') {
alert('Failed from timeout');
}
alert(textStatus);
});
The php code that provides the response prints the response with :
$data = (object)array_merge(['projectReportData' => $projectReportData]);
header("Content-Type: application/json");
$post_data = json_encode($data, JSON_FORCE_OBJECT);
ob_start('ob_gzhandler');
echo new JResponseJson($data);
ob_end_flush();
jexit();
This ajax works fine sometimes and is able to parse the JSON. But most of the times gives "parsererror".
Below code fetch the data from the DB :
$db = JFactory::getDbo();
$query = "CALL getReportData('" . $startweek . "','" . $endweek . "')";
$db->setQuery($query);
$res = $db->query($query);
$returnArr = [];
$i = 0;
while( $r = $res->fetch_assoc()){
$projectReportData[$i] = $r;
$i++;
}
when i change dataType to text the pointer reaches the .done() but console.log(response) returns a blank.

Related

Ajax never initiating success: when using xhrFields

I am having trouble getting the success call to fire in my ajax request. I know the communication is working fine, but the last call in my PHP script, which is a return json_encode($array); will fire as if it is a part of the onprogress object. I would like to "break" the onprogress call and run the success function on the last data sent via return json_encode when the PHP script has terminated...
Here is my AJAX call:
$( document ).ready(function(e) {
var jsonResponse = '', lastResponseLen = false;
$("#btn_search").click(function(e){
var firstname = document.getElementById('firstname').value;
var lastname = document.getElementById('lastname').value;
$.ajax({
type: "POST",
url: 'search.php',
data: $('#search_fields').serialize(),
dataType: "json",
xhrFields: {
onprogress: function(e) {
var thisResponse, response = e.currentTarget.response;
if(lastResponseLen === false) {
thisResponse = response;
lastResponseLen = response.length;
} else {
thisResponse = response.substring(lastResponseLen);
lastResponseLen = response.length;
}
jsonResponse = JSON.parse(thisResponse);
document.getElementById('progress').innerHTML = 'Progress: '+jsonResponse.msg;
}
},
success: function(data) {
console.log('done!');
document.getElementById('progress').innerHTML = 'Complete!';
document.getElementById('results').innerHTML = data;
}
});
e.preventDefault();
});
});
And here is the basic PHP server script:
<?php
function progress_msg($progress, $message){
echo json_encode(array('progress' => $progress, 'msg' => $message));
flush();
ob_flush();
}
$array = array('msg' => 'hello world');
$count = 0;
while($count < 100){
progress_message($count, "working....");
$count += 10;
sleep(2);
}
return json_encode($array);
?>
I made your code work, there were 2 errors. First, in your while loop, your function name is incorrect, try this:
progress_msg($count, "working... ." . $count . "%");
Secondly, the very last line outputs nothing, so technically you don't get a "successful" json return. Change the last line of your server script from:
return json_encode($array);
to:
echo json_encode($array);
UPDATE: Full working code with hacky solution:
Ajax:
$( document ).ready(function(e) {
var jsonResponse = '', lastResponseLen = false;
$("#btn_search").click(function(e){
var firstname = document.getElementById('firstname').value;
var lastname = document.getElementById('lastname').value;
$.ajax({
type: "POST",
url: 'search.php',
data: $('#search_fields').serialize(),
xhrFields: {
onprogress: function(e) {
var thisResponse, response = e.currentTarget.response;
if(lastResponseLen === false) {
thisResponse = response;
lastResponseLen = response.length;
} else {
thisResponse = response.substring(lastResponseLen);
lastResponseLen = response.length;
}
jsonResponse = JSON.parse(thisResponse);
document.getElementById('progress').innerHTML = 'Progress: '+jsonResponse.msg;
}
},
success: function(data) {
console.log('done!');
dataObjects = data.split("{");
finalResult = "{" + dataObjects[dataObjects.length - 1];
jsonResponse = JSON.parse(finalResult);
document.getElementById('progress').innerHTML = 'Complete!';
document.getElementById('results').innerHTML = jsonResponse.msg;
}
});
e.preventDefault();
});
Search.php:
<?php
function progress_msg($progress, $message){
echo json_encode(array('progress' => $progress, 'msg' => $message));
flush();
ob_flush();
}
$array = array('msg' => 'hello world');
$count = 0;
while($count <= 100){
progress_msg($count, "working... " . $count . "%");
$count += 10;
sleep(1);
}
ob_flush();
flush();
ob_end_clean();
echo json_encode($array);
?>
The problem with the "success" method of the ajax call was that it couldn't interpret the returning data as JSON, since the full return was:
{"progress":0,"msg":"working... 0%"}{"progress":10,"msg":"working... 10%"}{"progress":20,"msg":"working... 20%"}{"progress":30,"msg":"working... 30%"}{"progress":40,"msg":"working... 40%"}{"progress":50,"msg":"working... 50%"}{"progress":60,"msg":"working... 60%"}{"progress":70,"msg":"working... 70%"}{"progress":80,"msg":"working... 80%"}{"progress":90,"msg":"working... 90%"}{"progress":100,"msg":"working... 100%"}{"msg":"hello world"}
Which is not a valid JSON object, but multipje JSON objects one after another.
I tried removing all previous output with ob_end_clean(); , but for some reason I can't figure out, it didn't work on my setup. So instead, the hacky solution I came up with was to not treat the return as JSON (by removing the dataType parameter from the AJAX call), and simply split out the final Json element with string operations...
There has got to be a simpler solution to this, but without the use of a third party jQuery library for XHR and Ajax, I couldn't find any.

Ajax request fails in Meteor but is correct in localhost test

I try to get some data from my MySql db. I have 2 files:
// client/book.js
$(document).ready(function () {
$("#btnJSonDB").bind("click", function () {
var request = $.ajax({
url: "book.php",
type: "GET",
data: "",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(result) {
console.log(result);
}
}); //end ajax
request.fail(function( jqXHR, textStatus ) {
console.log("Request failed: " + textStatus);
});
}); //end click
}); //end ready
and server side:
// server/book.php
$db = new mysqli(DATA_HOST,DATA_UTENTE,DATA_PASS,DATA_DB );
$select = "SELECT * FROM bk_book";
$strJSon = "{\"book\":{}}";
$query = #mysqli_query($db,$select);
if( $query ) {
$result = [];
while($result[] = mysqli_fetch_array($query, MYSQLI_ASSOC));
#mysqli_close($db);
$strJSon = "{\"book\":" . json_encode($result) . "}";
}
echo $strJSon;
I try in my localhost space (windows-xampp) and all it's ok, In meteor I recive an error message:
Parse error
I try to comment datatype (json problem?) and I see the html page without my data.
The result is a correct json format:
{
"book":[
{
"nrent":"xxxxxx",
"start_date":"2017-01-05",
"end_date":"2017-01-12",
"user_ID":"15",
"booking_status":"estimate",
"note":"",
"adults_numb":"0",
"children_numb":"0",
"booking_bill":"630.00",
"name":"Camera Bi",
"first_name":"dddd",
"last_name":"ddd",
"mail":"dddd#dddd.it",
"telephone":"ddddddd"
},
{
"nrent":"fffff",
"start_date":"2017-01-08",
"end_date":"2017-01-27",
"user_ID":"25",
"booking_status":"active",
"note":"",
"adults_numb":"2",
"children_numb":"0",
"booking_bill":"1710.00",
"name":"Camera Ba",
"first_name":"pippo",
"last_name":"puppo",
"mail":"fff#pippfffo.it",
"telephone":"ffffff"
},
{
"nrent":"aaaaa",
"start_date":"2017-01-28",
"end_date":"2017-02-01",
"user_ID":"24",
"booking_status":"estimate",
"note":"",
"adults_numb":"0",
"children_numb":"0",
"booking_bill":"380.00",
"name":"Camera Ba",
"first_name":"ffff",
"last_name":"wwww",
"mail":"no#email.it",
"telephone":""
},
null
]
}
I try the https://jsonformatter.curiousconcept.com/ and is correct
$db = new mysqli(DATA_HOST,DATA_UTENTE,DATA_PASS,DATA_DB );
$select = "SELECT * FROM bk_book";
$jsonObject = new stdclass();
$query = #mysqli_query($db,$select);
if( $query ) {
$result = [];
while($result[] = mysqli_fetch_array($query, MYSQLI_ASSOC));
#mysqli_close($db);
$jsonObject->book = $result;
}
header("Content-Type: application/json; charset=utf-8", true);
echo json_encode($jsonObject);

Ajax call doesn't work from iPhone app and arduino

I've created an Arduino project wich sends the coordinates to an URL. The URL does some ajax calls. In the browser it works fine, but when I'm trying it with the Arduino it doesn't work. So I tried to do the same thing with an iOS app, but I got the same problem. This is the code on the page that the Arduino and iOS app request.
var directionsService = new google.maps.DirectionsService();
var base_url = window.location;
var received_data = <?php echo json_encode($received_data); ?>;
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id']},
type: 'GET',
dataType:"jsonp",
jsonp:"callback",
success: function (response){
var error = [];
var total = response.length;
for (var type in response) {
if(response[type].types == 'area'){
var x = checkInsideCircle(response[type].longitude, response[type].latitude, received_data['longitude'], received_data['latitude'], response[type].reach / 1000);
if(x == false){
// Outside
error.push(true);
}else{
// Inside
error.push(false);
}
}else if(response[type].types == 'route'){
// Check route
checkOnRoute(response[type].start_latitude, response[type].start_longitude, response[type].end_latitude, response[type].end_longitude, response[type].type, response[type]['reach'], type, function(result) {
error.push(result);
if(error.length == total){
if(error.indexOf(false) >= 0){
// Device is inside route or area
outside = false;
}else{
// Send data to database
$.ajax({
url: 'http://gps-tracker.domain.nl/_api/handler.php',
data: { action: 'post', device_id: received_data['device_id'], longitude: received_data['longitude'], latitude: received_data['latitude']},
type: 'GET',
dataType: 'json',
success: function (response){
console.log('good');
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
}
}
});
}
}
},error: function(jq,status,message) {
alert('A jQuery error has occurred. Status: ' + status + ' - Message: ' + message);
}
});
Here is the code from the handler.php file, that the ajax request requests.
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : false;
// Switch actions
switch($action) {
case 'get':
$callback ='callback';
if(isset($_GET['callback'])){
$callback = $_GET['callback'];
}
$routes = ORM::for_table('gps_tracker_route')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_route.device_id'))
->where('gps_tracker_route.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($routes = $routes->find_many()){
foreach($routes as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response1[$k] = $v;
$response1[$k]['types'] = 'route';
}
}
}
$area = ORM::for_table('gps_tracker_area')
->inner_join('gps_tracker_device', array('gps_tracker_device.device_id', '=', 'gps_tracker_area.device_id'))
->where('gps_tracker_area.device_id', $_GET['device_id'])
->where('gps_tracker_device.device_id', $_GET['device_id']);
if($area = $area->find_many()){
foreach($area as $k=>$v){
$v = $v->as_array();
if($v['status'] == 'on' or strtotime(date('Y-m-d H:i:s')) > strtotime($v['start_time']) and strtotime(date('Y-m-d H:i:s')) < strtotime($v['end_time'])){
$response2[$k] = $v;
$response2[$k]['types'] = 'area';
}
}
}
if(isset($response1) and isset($response2)){
$response = array_merge($response1, $response2);
}elseif(isset($response1)){
$response = $response1;
}else{
$response = $response2;
}
if ( isset($response) ) {
if ( is_array($response) ) {
if (function_exists('json_encode')) {
header('Content-Type: application/json');
echo $callback.'(' . json_encode($response) . ')';
} else {
include( ABSOLUTE_PATH . '/classes/json.class.php');
$json = new Services_JSON();
echo $json->encode($response);
}
} else {
echo $response;
}
exit(0);
}else{
exit();
}
break;
case 'post':
$_GET['timestamp'] = date("Y-m-d H:i:s");
$record = ORM::for_table('gps_tracker_device_logging')->create($_GET);
$record->save();
$item = ORM::for_table('gps_tracker_device_logging')
->where('id', $record->id);
if($item = $item->find_one()){
$item = $item->as_array();
echo json_encode($item);
}
break;
default:
die('invalid call');
}
Can someone help me?
EDIT
I think it is something with Javascript. I don't know if it's possible to use javascript when a device, like Arduino, makes a http request to a server. Someone know?
I think that it's because you need a Web Browser that supports JavaScript.
I don't work with Arduino, but from what I know it does not have a "real" Web Browser - it can only pull/download data but can't execute the JS part.
For JS to work you need something to run it. That is why it works in a the browser.

PHP Jquery JSON catching

Here's my php responding to my jQuery calls.
<?php
if ( isset( $_POST['icnumber']) && $_POST['icnumber'] != '' ) {
$custic = $_POST['icnumber'];
$response = array();
$response['status'] = 'false';
$sql ="SELECT * FROM ctrl_cust WHERE cust_ic='$custic'";
$raw = mysql_query($sql,$link) or die('Query 1 '.mysql_error());
if ( $data = mysql_fetch_assoc( $raw ) ) {
$response['status'] = 'true';
$response['custid'] = $data['cust_id'];
$response['custname'] = $data['cust_name'];
}
header("Content-Type: application/json", true);
echo json_encode($response);
}
?>
and here's the jQuery
$(function() {
$('#icnumber-form').submit(function() {
var icno = $('#icnumber').val();
$.ajax({
type : 'POST',
url : 'php/create_process.php',
data : icno,
dataType: 'json',
success : function(data){
console.log(data);
},
beforeSend:function(){
$('.cust-exist-view').fadeIn();
}
});
return false;
})
});
The thing is, console.log returns NULL, but when I submit the form without javascript enabled, it returns this :
{"status":"true","custid":"00001","custname":"John"}
I wonder what is the problem...I've been running around in circles for hours...Help me please?
icnumber is not getting post, change data: icno, to data: {icnumber: icno}, and try

Jquery ajax parsing error for json

I am trying to send some data using php and jquery ajax using json datatype method.
Here is my code:
$("#username").on("keyup change keypress", function () {
var username = $("#username").val();
$.ajax
({
type: "POST", // method send from ajax to server
url: window.location.protocol + '//' + window.location.host + '/' + "admin/admins/user_exists",
data: {
username: username
},// Specifies data to be sent to the server
cache: false, // A Boolean value indicating whether the browser should cache the requested pages. Default is true
contentType: "application/json",
dataType: 'json', // The data type expected of the server response.
success: function (response_data_from_server) {
for (var key in response_data_from_server)
var result = response_data_from_server[key] + ""; // JSON parser
if (result == 'true') {
console.log("---------------- in true");
$("#username_alert").text("ERROR");
$('#username_alert').removeClass("alert-success");
$("#username_alert").css("visibility", "visible");
}
else {
if (result == 'false') {
console.log("---------------- in false");
$("#username_alert").text("NO ERROR");
$("#username_alert").css("visibility", "visible");
$('#username_alert').addClass("alert-success");
}
else {
if (result == 'empty') {
console.log("---------------- in empty");
$("#username_alert").text("ERROR");
$("#username_alert").css("visibility", "visible");
$('#username_alert').removeClass("alert-success");
}
}
}
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
}
});
});
and it always goes to an error function. The error that I receive is the following:
parsererror SyntaxError: Unexpected token  {}
My url location is correct and is indeed returning the correct json format. Here is my php code:
public function user_exists()
{
$username = $this->input->post("username");
$is_exists = "false";
$this->load->database();
if ($username != "")
{
$rows = $this->db->query("
SELECT * FROM `admins` WHERE `username` = '" . $username . "'
")->num_rows();
if ($rows > 0)
{
$is_exists = "true";
}
else
{
$is_exists = "false";
}
}
else
{
$is_exists = "empty";
}
$arr = array ('result' => $is_exists );
$response = json_encode($arr);
echo $response;
}
I've debugged it million times, the firebug sees the response as correct and expected json, however the client side seems to refuse to get it as a json respone, for what I believe.
Will appreciate any help!
...
header('Content-type: application/json');
echo $response;
Maybe you could use "header('Content-type: application/json');" before "echo"

Categories