Slim REST API call error with no error message (JQuery) - php

I tried to make a GET call from a self written API in javascript (JQuery). I get an error but there is no message included.
Client code looks like this
$(document).ready(function () {
$.ajax({
type: "GET",
url: "APIURL...",
headers: {"Content-Type": "application/json;odata=verbose", "Accept": "application/json;odata=verbose", "crossDomain": "true", "credentials":"include"},
success: function (data) {
console.log(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(textStatus); //output: error
console.log(errorThrown); //output:
}
});
});
Also tested this with another url of a REST Test API https://jsonplaceholder.typicode.com/todos/1. This works fine, it outputs the expected data in the success function. So I think the problem is somewhere in my own API.
I made the API with PHP and the Slim Framework. Code looks like this
$app->get ( '/test', function ($request, $response) {
$data["test"] = "data";
$json = json_encode ( $data );
$response->write ( $json );
return $response;
});
This is the called function from my jquery code. In the browser its output is as expected {"test":"data"}
The server where my API runs is reachable from the internet. Any solutions or suggestions?

Related

Empty PHP response object in AJAX but only on success

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);

Angularjs Get Method

Getting the error below in console and data is not fetching from mysql. Can anyone suggest on the error below:
Used angularjs, php, mysql and materializecss
Error: $http.get(...).success is not a function
Here is the code of my controller:
.controller('dashBoardCtrl', ['$scope', '$http', function ($scope, $http)
{
$http.get("dbconnection/db_read.php")
.success(function(data)
{
$scope.data = data;
console.log(data);
})
.error(function()
{
$scope.data = "error in fetching data";
});
}]
);
Can you try
$http.get().then(function(result){console.log(result)});
I believe .success is deprecated.
You're more than likely using AngularJS 1.6+
.success(fnSuccess) and .error(fnError) don't exist any more.
Use .then(fnSuccess, fnError) instead.
So
$http.get(...).success(function(){})
is now
$http.get(...).then(function success() {}, function error() {});
Let's look at the documentation:
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
So you pass your success and error callbacks to then() not success().

Simple Ajax Request to Laravel Not Working

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.

Ajax Doesn't give me anything in the console?

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.

JQuery AJAX Issue without error

So I am adding a list of stores to a web page via a jQuery AJAX request. This little utility is not dynamic, just database driven. I have decided to use jQuery/AJAX to transfer the data because when I try to embed PHP in our current PHP CMS, I get a bunch of conflicting errors.
The problem I am having is that I am getting a jQuery AJAX error when trying to make the request to the PHP script, and I am not sure why.
Here is my AJAX request
$(document).ready(function(){
$.ajax({
type:"POST",
url:"getStores.php",
dataType: "json",
success:function(data){
results(data);
},
error: function(data) {
console.log(data.error);
}
});
});
The cryptic console error i am getting is this
function (){if(c){var a=c.length;m(arguments),i?k=c.length:e&&e!==!0&&(j=a,n(e[0],e[1]))}return this}
Here is my PHP code if it will be helpful:
//database connection
$return_arr = array();
$sql = mysql_query("SELECT * FROM where_to_buy");
while($row = mysql_fetch_array($sql, MYSQL_ASSOC))
{
$row_array['store_name'] = $row['store_name'];
$row_array['store_url'] = $row['store_url'];
array_push($return_arr,$row_array);
}
echo json_encode($return_arr);
I think the problem might be because I wrapping my JSON in an array?
EDIT:: JSON output from php script as requested
[{"store_name":"Example 1","store_url":"http:\/\/www.example1.com"},{"store_name":"Example 2","store_url":"http:\/\/www.example2.com"}]
Thanks for any help!
The reason you are getting that weird error message is that the error callback for the jQuery ajax function takes 3 arguments instead of 1, as described in the docs here: http://api.jquery.com/jQuery.ajax/
The first argument is a jQuery-special XMLHttpRequest object, which has a property called error that contains the function you are seeing logged to your console. The actual error that occurred during execution of your ajax call is the passed in to the error callback as the 3rd argument.
To see it, you should do something like:
$(document).ready(function(){
$.ajax({
type:"POST",
url:"getStores.php",
dataType: "json",
success:function(data){
results(data);
},
error: function(jqXHR, text, error) {
console.log(error);
}
});
});
That will get you closer to the real problem.
UPDATE:
Please show the output from your php script. It may be that it is not returning valid json. As noted in the php docs ( http://php.net/manual/en/function.json-encode.php ), [json_encode] only works with UTF-8 encoded data.
You might also check in to json_last_error ( http://php.net/manual/en/function.json-last-error.php ) to see if the encoding failed for some reason.
UPDATE 3:
It seems like your problem may be the path to the php script.
try it with:
$(document).ready(function(){
$.ajax({
type:"POST",
url:"/getStores.php", // <-- notice the leading slash!!!
//dataType: "json",
success:function(data){
//results(data);
console.log(data);
},
error: function(jqXHR, text, error) {
console.log(error);
}
});
});
or, putting it all back together if the above logs the correct json output to the console...
$(document).ready(function(){
$.ajax({
type:"POST",
url:"/getStores.php",
dataType: "json",
success:function(data){
results(data);
},
error: function(jqXHR, text, error) {
console.log(error);
}
});
});

Categories