Trying simple return and display of user info using ajax with laravel backend. Using latest JQuery and Laravel and MySQL. Here's the simple route:
Route::get('users', function()
{
$users = User::all();
return $users;
});
This works fine when calling by url in browser.
Here's the simple ajax request:
$().ready(function() {
$.ajax({
url: "http://xx.xxx.xxx.xxx/users",
type: "GET",
cache: false,
dataType: "jsonp",
jsonpCallback: "JsonpCallback"
})
.done(function( data )
{
JsonpCallback( data );
})
.fail(function( jqXHR, textStatus, errorThrown )
{
alert( "Request failed: " + textStatus + " / " + errorThrown );
});
function JsonpCallback( json )
{
$( '#mainContent' ).html( json.result );
}
return false;
});
The user records are being returned in to the dom and I can see them via dev tools network response, but the .fail kicks every time and the callback is never called. The fail is:
Request failed: parsererror / Error: JasonpCallback was never called.
I have tried every solution I can find for a few days now and could really use help. It has to be something simple that I'm missing.
jQuery is expecting a jsonp response, but return $users is returning plain json. Either switch dataType to json, or instead:
return Response::json($users)->setCallback(Input::get('callback'));
...from your route.
See the Laravel docs under creating a JSONP response.
Related
To receive my response object from my PHP server I have the code down below.
First of all, it works. What does not work is that if my first PHP condition is met, the success function in my Ajax responds correctly but only without using the data object.
This is my AJAX function:
$.ajax({
type: "PUT",
url: "http://server/register",
contentType: "application/json",
data: '{"username":"' + username + '", "password":"' + password + '"}',
success: function(data) {
console.log(data) // The output in my dev tools under Firefox is just a blank line, no error message or even "undefined".
console.log("Success") // Works!
if(data.status == 200){
console.log("Test 1") // Doesn't work. Although status code 200 is shown to me.
}
},
error: function(data) {
console.log(data) // This works! I can see the content of the object. The correct status code (409) is shown to me.
if(data.status == 409){
console.log("Test 2") // Works
}
}
});
This is my PHP function:
public function register($request, $response)
{
...
if(condition-1) {
echo("Condition 1 works!"); // Works.
return $response->withStatus(200);
} elseif(condition-2) {
echo("Condition 2 works!"); // Works too.
return $response->withStatus(409);
}
}
I don't see why there is no data object. I'm using the Slim 3 Framework and could probably return a JSON object like this:
$content = ["foo" => 'bar', ...] ; //Any data you wish to return
return $response->withJson($content);
But so far my whole code works without using JSON objects. Even if I var_dump the $response object, I can see that on the server side it is there.
if(condition-1) {
var_dump($response->withStatus(200)); // Works. I can see it.
}
There's a lot wrong here, so I've done my best to point out what I see wrong, and hopefully with the changes I'm going to suggest you will have success.
If you are trying to use data.status in your ajax success function, then it looks like you think you are returning json, but you aren't. Even if you are, you are corrupting it by echoing "Condition 1 works!".
So think about it, if you have a json response like this:
{'a':'1'}
And you echo something out before it, your response is corrupted, and looks like this:
Condition 1 works!{'a':'1'}
Same corruption occurs if PHP throws an error your way, so be aware of that.
You should also be declaring a dataType for your ajax request, so:
$.ajax({
type: "PUT",
url: "http://server/register",
contentType: "application/json",
data: JSON.stringify({
"username": username,
"password": password
}),
dataType: 'json', // <-- THIS LINE IS IMPORTANT
success: function(data, textStatus, jqXHR) {
// ...
},
error: function(jqXHR, textStatus, errorThrown) {
// ...
}
});
Note: you were single quoting your data object, so you were doing it the hard way. Just use JSON.stringify on a JS object like I did!
Since my code expects a json response, make sure to look at the other answer here, as it shows how to send back a proper json response with slim.
Finally, in your ajax success function, data.status is not ever going to be available. Docs for jQuery show that there are three parameters, (data, textStatus, jqXHR) and data is specifically for the data, not the HTTP status code or any headers.
I put together a full working example of a mini Slim app. It's fully tested and works (it's just not awesome, so don't laugh):
<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;
require 'vendor/autoload.php';
$app = new \Slim\App;
$app->get('/', function (Request $request, Response $response) {
$response->getBody()->write('<!doctype html>
<html>
<head>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script>
$(document).ready(function(){
$("p").on("click", function(){
var username = "kookoopapa";
var password = "gr3atp4ssWerd";
$.ajax({
type: "PUT",
url: "/register",
data: JSON.stringify({
"username": username,
"password": password
}),
contentType: "application/json",
dataType: "json", // <-- THIS LINE IS IMPORTANT
success: function(data, textStatus, jqXHR) {
alert( data.a );
alert( data.b );
},
error: function(jqXHR, textStatus, errorThrown) {
// ...
}
});
});
});
</script>
</head>
<body>
<p>Click</p>
</body>
</html>');
return $response;
});
$app->put('/register', function (Request $request, Response $response) {
$php_input = file_get_contents('php://input');
$vars = json_decode( $php_input, TRUE );
$content = [
'a' => $vars['username'],
'b' => $vars['password']
];
return $response->withStatus(200)->withJson($content);
});
$app->run();
Try to use the following return:
$content = ["foo" => 'bar', ...] ; //Any data you wish to return
return $response->withStatus(200)->withJson($content);
I am trying to delete address by using ajax call and data type as json:
Ajax call is as below:
$(".delete a").on('click', function() {
url: 'index.php?route=account/address/delete',
type: 'post',
data: "address_id="+addid,
dataType: 'json',
success: function(html) {
$("#msg").html('Deleted Address Successfully ');
},
error: function(xhr, ajaxOptions, thrownError) {
delcheckbox.html('<i class="fa fa-trash-o"></i>');
alert(thrownError + "\r\n" + xhr.statusText + "\r\n" + xhr.responseText);
}
});
and in account/address/delete i wrote a new Post request condition as below:
public function delete() {
/* Opencart Pre written functions are here */
if (isset($this->request->post['address_id'])&&$this->validateDelete()) {
$json = array();
$this->model_account_address->deleteAddress($this->request->post['address_id']);
/* Unset Session variables same as get function of opencart */
/*to get json as response*/
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
}
When i execute ajax call then address is deleted successfully but as a reponse the error block of ajax is shown and error says as below screeenshot
Please suggest.
and please explain how operations pre.customer.delete.address and post.customer.delete.address work??
You are getting a page returned in your response. This indicates you might be getting a 404, another kind of error, or are calling onto a function that renders a page. Make sure none of this is happening.
I have a little question about Ajax calls in Mootools.
I wrote a handler script and a listener script in Jquery using AJAX but i cant figure out how to convert it so it works with mootools instead of Ajax.
The function is called using a html link tag with onclick='changePage($page, $total)'
This is the original JQuery Ajax call. it gets returned in the Ajax file as an array.
The variable gets returned as followed:
$data = array();
$data['result'] = '1';
$data['html'] = $this->result; //Returns Pagination bar with current selected page.
$data['html2'] = $this->result2; //Returns a block of HTML (result of Solr request styled with bootstrap
JQuery version of the script
function changePage(page, total) {
$.ajax({
url: '/public/ajax.php?do=getPageView',
type: 'POST',
dataType: 'json',
data: {
page: page,
total: total,
//type : type
},
success: function(data) {
//console.log(data.result);
if (data.result == 1) {
$('#placeHolder').html(data.html);
$('#vrouwen').html(data.html2);
} else if (data.status == 2) {
//do nothing :) - nothing has been input
} else {
alert("Fout!!\n" + textStatus + "\n" + errorThrown);
}
},
error: function error(jqXHR, textStatus, errorThrown) {
alert("Fout!!\n"
+ textStatus + "\n" + errorThrown);
}
});
};
My presumed Mootools version of the script
function changePage(page, total) {
var ajax = new Request({
async: false,
url: '/public/ajax.php?do=getPageView',
method: 'POST',
dataType: 'json',
data: {
'page': page,
'total': total,
//type : type
},
onSuccess: function(data) {
//console.log(data.result);
if (data.result == 1) {
$('placeHolder').set('html', data.html);
$('vrouwen').set('html', data.html2);
} else if (data.status == 2) {
//do nothing :) - nothing has been input
} else {
//alert("Fout!!\n" + textStatus + "\n" + errorThrown);
}
}
});
ajax.send();
};
In the view i have a div named placeholder, thats where the pagination bar goes.
And html2 gets inserted into the div with id='vrouwen'.
Hope you guys can help me out on this one.
--EDIT---
Figured it out after brainstorming with a few fellow programmers. posting the findings here for all to see.
The difference lies in the way Jquery and Mootools handle returned values.
Apperantly JQuery handles returned values as JSON objects when you set dataType: 'json'.
Mootools does not do this so i added to the onSuccess function the following:
onSuccess: function(data) {
data = JSON.decode(data);
//console.log(data.html2);
if (data.result == 1) {
$('placeHolder').set('html', data.html);
$('vrouwen').set('html', data.html2);
} else if (data.status == 2) {
//do nothing :) - nothing has been input
} else {
//alert("Fout!!\n" + textStatus + "\n" + errorThrown);
}
}
Now it properly replaces the Divs.
Mootool Request is An XMLHttpRequest Wrapper
onSuccess attached Method is Fired when the Request is completed successfully.
The arguments returned to the attached Handler are responseText & responseXML
responseText - (string) The returned text from the request.
responseXML - (mixed) The response XML from the request.
Request.JSON - Wrapped Request with automated receiving of
JavaScript Objects in JSON Format. Means it is made for json requests
and when it receives data it converts it to json object.
Here onSuccess Fired when the request completes. This overrides the signature of the Request success event.
The arguments returned to the attached Handler are responseJSON & responseText
responseJSON - (object) The JSON response object from the remote request.
responseText - (string) The JSON response as string.
Updated Question to better reflect the communities support
Based on community support I have changed the Ajax function to be as such:
(function($){
$(document).ready(function(){
$('a').click(function(e){
var el = $(this).prev('input[type="checkbox"]');
if(el.is(':checked')){
el.prop('checked',false);
}
$.ajax({
url : "http://localhost/wordpress/wp-content/themes/Aisis-Framework/CoreTheme/AdminPanel/Template/Helper/UncheckPackageThemeHelper.php",
type : 'GET',
data : { 'element_name' : el.prop('name') },
success: function(data, textStatus, jqXHR){
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown ){
console.log(jqXHR, textStatus, errorThrown);
}
});
e.preventDefault();
});
});
})(jQuery);
The resulting PHP Class is as such:
class CoreTheme_AdminPanel_Template_Helper_UncheckPackageThemeHelper{
private $_element_name = null;
public function __construct(){
if(isset($_GET['element_name'])){
$this->_element_name = $_GET['element_name'];
echo $this->_element_name;
}
}
}
The network tab shows that I have some out put from activating the Jquery which I have shown below:
The Console is spitting out no errors, yet not echoing the element name. I have read up on the Jquery Ajax API and everything I have been doing, thus far, seems to be correct. Yet I am not getting the desired out put.
Note: The response tab is empty.... In other words I am not getting a response back.
You're not passing in the event to your click handler.
Use.
$('a').click(function(e){
// Your code
});
$.ajax({
url : "<?php echo CORETHEME_ADMIN_TEMPLATE_HELPER_URL . 'UncheckPackageThemeHelper.php'; ?>",
type : 'GET',
data : { 'element_name' : el.prop('name') },
success: function(result) {
console.log(result)
},
error: function(jqXHR, textStatus, errorThrown ){
console.log(jqXHR, textStatus, errorThrown);
}
});
Simplify the situation. Just for a moment, change your AJAX processor file (UncheckPackageThemeHelper.php) to read like this:
UncheckPackageThemeHelper.php
<?php
$test = $_POST['element_name'];
$r = 'PHP received: [' .$test. ']';
echo $r;
die();
Also, change your AJAX success function to read like this:
success: function(result) {
alert(result);
},
At least, this will show you that your AJAX is getting through.
Then, start adding things back into your AJAX processor file (one or two at a time) and keep echoing something out so that you can discover where the error is happening.
So I was doing a lot of things wrong. But this is the only way it works, for me - please post your comments if you have better solution.
In the class, I have to do this:
class CoreTheme_AdminPanel_Template_Helper_UncheckPackageThemeHelper{
private $_element_name = null;
public function __construct(){
if(isset($_GET["element_name"])){
$this->_element_name = $_GET["element_name"];
echo json_encode($this->_element_name);
}
}
}
new CoreTheme_AdminPanel_Template_Helper_UncheckPackageThemeHelper();
The class cannot be instantiated in the .phtml file with the resulting Ajax or the request is never sent back. Also notice the json_encode You cannot pass regular variables back to Ajax - when in a class (I think) - How ever when not in a class it seems to work - clarification is needed.
The Ajax then looks like this:
(function($){
$(document).ready(function(){
$('a').click(function(e){
var el = $(this).prev('input[type="checkbox"]');
if(el.is(':checked')){
el.prop('checked',false);
}
$.ajax({
url : "http://localhost/wordpress/wp-content/themes/Aisis-Framework/CoreTheme/AdminPanel/Template/Helper/UncheckPackageThemeHelper.php",
type : 'GET',
data : { 'element_name' : el.prop('name') },
success: function(data, textStatus, jqXHR){
console.log(data);
},
error: function(jqXHR, textStatus, errorThrown ){
console.log(jqXHR, textStatus, errorThrown);
}
});
e.preventDefault();
});
});
})(jQuery);
The Data that comes back is what I expect: "aisis_options[package_RelatedPosts]"
There ar a couple of issues with this answer - One I dont understand why I have to instantiate the class inside the file its written in, and two not sure why I have to encode the response in a class, but not when its just a "script kiddy" file.
When you use Jquery or Ajax to call a page or script, which loads into a div,
or example
$.post('pagename.php', $(#cpay'.$id.'").serialize(), function(data) { $('#conSupp".$id."').html(data);
is there a way to display an error message in the div if the page fails to load
Many thanks
If you are using jquery 1.5 or above, the post will return a jqXhr object. If so, you could do something like this:
$.post('pagename.php', data, function(data) {
//success, do stuff with the data object
}).fail(function(jqXhr, ajaxOptions, thrownError){
//something went wrong
alert('Error: ' + thrownError);
});
Yes, bind an error handler, by calling the .fail() function on the jqXhr object returned by the call to $.post():
$.post(url, data, function(data) {
...
}).fail(function(jqXhr, textStatus, errorThrown) {
// an error occurred - do something here
});
I prefer just doing:
$.ajax({
type: 'POST',
url : 'pagename.php',
data: $(#cpay'.$id.').serialize()
}).done(function(data {
$('#conSupp".$id."').html(data);
}).fail(function() {
$('#conSupp".$id."').html('An error occured');
});
It's a little longer, but I find it much easier to read an change to whatever I need, and it's exactly what $.post does internally anyway, so saves me a function call?