call rest api service from jquery - php

I am trying to understand restful services.i can create a class and define a function into this but when i call it through jquery it return null and when i call directly by typing url in address bar it return a json response
this is the code
class Api extends REST
{
public function processApi()
{
$func = strtolower(trim(str_replace("api/","",$_REQUEST['request'])));
if((int)method_exists($this,$func) > 0)
{
$this->$func();
}
else
{
$this->response('',404); // If the method not exist with in this class, response would be "Page not found".
}
}
private function json($data)
{
if(is_array($data))
{
return json_encode($data);
}
}
public function demo()
{
$error = array('status' => '200', "msg" => "OK");
$this->response($this->json($error), 200);
}
}
$api = new Api;
$api->processApi();
i just want to call demo method from jquery.this is what i am trying
$.post("db/api/demo",
function(data,status){
data = jQuery.parseJSON(data);
alert("Data: " + data + "\nStatus: " + status);
});
i am getting response through jquery when demo method is this
public function demo()
{
$error = array('status' => '200', "msg" => "OK");
echo json_encode($error);
//$this->response(json_encode($error), 200);
}

You should send datatype to server.
Try this code:
$.post( "db/api/demo")
.done(function( data ) {
$.each(data, function(index, element) {
alert('Data: ' + element.data + ' Status: ' + element.status);
});
}, "json");

Related

FutureBuilder data not getting updated on button click

So starting by giving a brief of the issue. I have defined a function to get data from my api and the function is:
Future<void> getProductDetailsData(params) async {
if (_isNetworkAvail) {
await apiBaseHelper
.getAPICall(getProductData, params)
.then((getdata) async => {
if (getdata.containsKey('data'))
{
productDataList = (getdata['data']['items'] as List)
.map((data) => ProductModel.fromJson(data))
.toList(),
tempProductDataList.addAll(productDataList),
}
});
} else {
setState(() {
_isNetworkAvail = false;
});
}
}
and the params I have given is Future<void> myData = getProductDetailsData({'id': widget.dealerId.toString()});
and then I have used myData in the future of the FutureBuilder.
now I have defined a MultiSelectDialogField and on its onConfirm I want to change the params so that I can get a particular data as per the given params. So for this I have done this
onConfirm: (results) {
setState(() {
myData = getProductDetailsData({
'id': widget.dealerId.toString(),
'categoryId': "23",
});
});
}
But the issue is that the FutureBuilder is not getting updated and only showing data with params as {'id': widget.dealerId.toString()}
You just need to use either await or .then to get value from future. Inside your .then you need to call setState.
Future<void> getProductDetailsData(params) async {
if (_isNetworkAvail) {
apiBaseHelper
.getAPICall(getProductData, params)
.then((getdata) async => {
if (getdata.containsKey('data'))
{
productDataList = (getdata['data']['items'] as List)
.map((data) => ProductModel.fromJson(data))
.toList(),
tempProductDataList.addAll(productDataList),
}
setState(() {}); //here
});
} else {
setState(() {
_isNetworkAvail = false;
});
}
}
better
Future<void> getProductDetailsData(params) async {
if (_isNetworkAvail) {
final getdata = await apiBaseHelper
.getAPICall(getProductData, params);
if (getdata.containsKey('data'))
{
....
}
setState(() {});
} else {
setState(() {
_isNetworkAvail = false;
});
}
also you can just use await and call setState on next line. Also you can use FutureBuilder.

Checkout-PHP-SDK and createOrder connection issue

Trying to implement the Checkout-PHP-SDK paypal API to createOrder JS call.As far as I understand I have to send the data from php file to js approval form. But I am getting an error when I press the "PayPal Pay" button.
The JS codes are like below :
<div id="paypal-button-container"></div>
<script>
function loadAsync(url, callback) {
var s = document.createElement('script');
s.setAttribute('src', url); s.onload = callback;
document.head.insertBefore(s, document.head.firstElementChild);
}
// Usage -- callback is inlined here, but could be a named function
loadAsync('https://www.paypal.com/sdk/js?client-id=AQgUM6x3URK1A-rcNIq56covuc0CYGv3pb5sYeL6-cqsO1HYV2CV6h4ur6BCly_1YYd3-UOMTNGtwQXd&currency=USD&disable-funding=card', function() {
paypal.Buttons({
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('https://example.com/TESTS.php', {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
// Call your server to finalize the transaction
onApprove: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order/' + data.orderID + '/capture/', {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
}
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
// Replace the above to show a success message within this page, e.g.
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '';
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
}).render('#paypal-button-container');
})
</script>
The php file is like this :
<?php
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
use PayPalCheckoutSdk\Core\PayPalHttpClient;
use PayPalCheckoutSdk\Core\SandboxEnvironment;
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
require __DIR__ . '/Checkout-PHP-SDK-develop/vendor/autoload.php';
// Creating an environment
$clientId = "AQgUM7x3URK1A-rcNIq56covuc0CYGv3pb5sYeL6-cqsO1HYV2CV6h4ur6BCly_1YYd3-UOMTNGtwQXd";
$clientSecret = "EDm88hmcFd6arhd7vaJ6d9AWjIvCScR6E6s0eM3OKqwf1uZt0G0KlLNUXG057vesyXR4eYP3RKDLJBz8";
$environment = new SandboxEnvironment($clientId, $clientSecret);
$client = new PayPalHttpClient($environment);
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = [
"intent" => "CAPTURE",
"purchase_units" => [[
//"reference_id" => "test_ref_id1",
"amount" => [
"value" => "100.00",
"currency_code" => "USD"
]
]],
"application_context" => [
"cancel_url" => "https://example.com/cancelled",
"return_url" => "https://example.com/success"
]
];
try {
$response = $client->execute($request);
print_r($response);
}catch (HttpException $ex) {
// echo $ex->statusCode;
print_r($ex->getMessage());
}
if(isset($_POST['id'])) {
$od_id = $response->result->id;
//echo $od_id;
$request1 = new OrdersCaptureRequest($od_id);
$request1->prefer('return=representation');
try {
// Call API with your client and get a response for your call
$response1 = json_encode($client->execute($request1));
return $response1;
// If call returns body in response, you can get the deserialized version from the result attribute of the response
return $request1;
}catch (HttpException $ex) {
echo $ex->statusCode;
// print_r($ex->getMessage());
}
}
Should I create, and catch the order in php file and then send it to JS? Actually is it the proper way to send the data? Any help would be highly appreciated. Thanks.
I have added CAPTURE method to the php file. and now it looks like above.
Each of your routes (the create route, and the capture route) must return a response that is a JSON string, and no other text nor HTML. print_r is not suitable.

ionic v3 when make and update in the app to the data it is updating in the database but not in the app

I am new to ionic and I am trying to understand an app that has basic http query to communicate with the database, but I am facing a problem.
There is a page that show a list which has been taken from the database. There are two operations that can be performed on this list - insert and update. The problem occurres when I try to make an update. The record in the database is updated but not the list in the application is not. However, when I insert a new record the list got updated with the new record including all previous changes, that were not shown in the list.
Here is the type script for the list page:
export class CrudHttpListPage {
items: any;
constructor(public loading: LoadingProvider, private toast: ToastProvider, public modal: ModalController, private crud: CrudHttpProvider) { }
ionViewDidLoad() {
this.load();
}
load() {
this.loading.present();
this.crud.read.then(res => {
this.items = res;
if (res) this.loading.dismiss();
});
}
add() {
let modal = this.modal.create('CrudHttpDetailPage', { action: 1 });
modal.present();
modal.onDidDismiss(data => {
console.log(data);
if (data) this.load();
});
}
edit(item) {
let modal = this.modal.create('CrudHttpDetailPage', { data: item, action: 2 });
modal.present();
modal.onDidDismiss(data => {
if (data) this.load();
});
}
Here is the typescript code for the add and edit page:
export class CrudHttpDetailPage {
private form: FormGroup;
action: number;
data: any = { title: '', text: '' };
constructor(private view: ViewController, private toast: ToastProvider, private loading: LoadingProvider, private crud: CrudHttpProvider, private fb: FormBuilder, public params: NavParams) {
this.action = params.data.action;
this.data = params.data && params.data.data || this.data;
console.log(params.data);
this.form = this.fb.group({
id: [this.data && this.data.id],
title: [this.data && this.data.title, Validators.required],
text: [this.data && this.data.text, Validators.required]
});
}
submit() {
this.loading.present();
console.log(this.form.value);
this.crud.save(this.form.value).then(data => {
// this.dataNotes.id = data;
console.log(data);
this.loading.dismiss();
this.view.dismiss(this.form.value);
}, err => {
console.log(err);
this.loading.dismiss();
this.toast.showWithClose(err);
this.close();
});
}
close() {
this.view.dismiss();
}
}
Here are the http operations:
const SERVER_URL: any = {
getNormal: ConstantVariable.APIURL + 'index.php/tbl_note',
getLimit: ConstantVariable.APIURL + 'limit.php',
};
#Injectable()
export class CrudHttpProvider {
limitData: number = 10;
datas: any = [];
constructor(public http: Http) {
this.datas = null;
}
get read() {
return new Promise(resolve => {
this.http.get(SERVER_URL.getNormal).map(res => res.json()).subscribe(data => {
console.log(data.dataNotes);
resolve(data.dataNotes);
});
});
}
save(item) {
let headers: any = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' }),
options: any = new RequestOptions({ headers: headers });
if (item.id) {
return new Promise((resolve, reject) => {
this.http.post(SERVER_URL.getNormal + '/' + item.id, item, options).map(res => res.json()).subscribe((data) => {
console.log(data);
resolve(data.dataNotes);
}, (err) => {
reject(err);
console.log("error: " + err);
});
});
}
else {
return new Promise(resolve => {
this.http.post(SERVER_URL.getNormal, item, options)
.map(res => res.json())
.subscribe(data => {
// console.log(data);
resolve(data.dataNotes[0].id);
}, error => {
console.log("error " + error);
});
});
}
}
and last here is the PHP file:
<?php
header('Access-Control-Allow-Origin: *');
require_once('config.php');
// get the HTTP method, path and body of the request
$method = $_SERVER['REQUEST_METHOD'];
$request = explode('/', trim($_SERVER['PATH_INFO'],'/'));
$input = json_decode(file_get_contents('php://input'),true);
// retrieve the table and key from the path
$table = preg_replace('/[^a-z0-9_]+/i','',array_shift($request));
$key = array_shift($request)+0;
// escape the columns and values from the input object
$columns = preg_replace('/[^a-z0-9_]+/i','',array_keys($input));
$values = array_map(function ($value) use ($link) {
if ($value===null) return null;
return mysqli_real_escape_string($link,(string)$value);
},array_values($input));
// build the SET part of the SQL command
$set = '';
for ($i=0;$i<count($columns);$i++) {
$set.=($i>0?',':'').'`'.$columns[$i].'`=';
$set.=($values[$i]===null?'NULL':'"'.$values[$i].'"');
}
// create SQL based on HTTP method
if ($method == "POST" AND $key != "") { $method = 'PUT'; }
if ($method == "GET" AND $key != "") { $method = 'DELETE'; }
switch ($method) {
case 'GET':
$sql = "select * from `$table`".($key?" WHERE id=$key":''); break;
case 'PUT':
$sql = "update `$table` set $set where id=$key"; break;
case 'POST':
$sql = "insert into `$table` set $set"; break;
case 'DELETE':
$sql = "delete from `$table` where id=$key"; break;
}
// excecute SQL statement
$result = mysqli_query($link,$sql);
// die if SQL statement failed
if (!$result) {
http_response_code(404);
die(mysqli_error());
}
// print results, insert id or affected row count
echo "{\"status\":\"ok\", \"dataNotes\":";
if ($method == 'GET') {
if (!$key) echo '[';
for ($i=0;$i<mysqli_num_rows($result);$i++) {
echo ($i>0?',':'').json_encode(mysqli_fetch_object($result));
}
if (!$key) echo ']';
} elseif ($method == 'POST') {
$set = '"id":"'.mysqli_insert_id($link).'"';
for ($i=1;$i<count($columns);$i++) {
$set.=($i>0?',':'').'"'.$columns[$i].'":';
$set.=($values[$i]===null?'NULL':'"'.$values[$i].'"');
}
echo "[{".$set."}]";
} elseif ($method == 'DELETE') {
echo '[{"id":"'.$key.'"}]';
} else {
echo mysqli_affected_rows($link);
}
echo "}";
// close mysql connection
mysqli_close($link);
The issue might be here:
edit(item) {
let modal = this.modal.create('CrudHttpDetailPage', { data: item, action: 2 });
modal.present();
modal.onDidDismiss(data => {
if (data) this.load(); // <---- seems this.load() is not executing
});
}
Seems this.load() is not executing after modal.onDidDismiss:
- check modal is dismissing
- check if data is not null/undefined
- check running this.load(), with no if() statement, does it run?
you may be able to find the answer there
edit(item) {
let modal = this.modal.create('CrudHttpDetailPage', { data: item, action: 2 });
modal.present();
modal.onDidDismiss(data => {
console.log('Modal has dismissed!!');
// if (data) this.load(); // comment for check
this.load();
});
}
i finally solved the problem. what cause the issue is that i have two files to make a connection to the database one for the website and the other is for the mobile application and it seems the one which i use in the mobile application is broken so i remove this file and connect to the old file and the problem solved

Why Ajax successful response is not accessible

I have a simple jQuery Ajax post call that works. A product is generated & added to cart.
I did find many answers but none seem to apply here.
But I cannot access the response content (post id) itself in my JS code.
In the code below - in comments - few more trials that I tried to no avail.
What am I missing??
Ajax post request:
jQuery.post(
ts_woo.ajax_url,
{'action': 'do_ts_woo',
'order': orderfilename,
'tilesize': globalTileSize,
'board': urlAtts,
'table': table
},
function(data) {
console.log("type of response="+ typeof data + " string=" + data); // data is a string but does not display it.
var response = jQuery.parseJSON(JSON.stringify(data));
console.log("do_ts_woo. Got id="+response); // undefined & so is response.id
pid = response;
if(pid>0){
//pid = response['id'];
console.log("do_ts_woo. SUCCESS response="+pid);
alert('Add to cart: ' + response.id);
ts_iframe(shopdomain + "/cart/?add-to-cart="+pid);
} else {
// ALWAYS end up here while all was successful...
console.log("do_ts_woo. FAILURE response="+response.id);
}
return false;
}
).done(function(response) {/* alert( "done:"+response );*/})
.fail(function(msg) {alert( "error msg="+msg );})
.always(function(response) {
//console.log("do_ts_woo. ALWAYS respone.id="+response.id); SAME PROBLEM HERE
});
Here is the PHP code
$pid = generate_woo_product("ts-".date("Ymd_His"), $product_price[1], $pimage, $allTable); // PRODUCT is GENERATED
error_log("pid =". $pid);
if ($pid > 0){
error_log ("product pid=".$pid." generated successfully");
echo $pid;
//tried wp_send_json_success($pid);
//tried wp_send_json_success(array('success' => true, 'id' => $pid));
} else error_log("do_ts_woo: FAIL generate_woo_product returned".$pid);
wp_die();
Please, try to use
wp_send_json(['pid' => $pid]);
exit;
instead of echo
And then access your $pid in js with
data.pid
Please, use data.pid without JSON.parse, cause data, in this case, needs to be object
If not - please, consider adding this code to you functions.php
add_action( 'rest_api_init', 'salient_child_rest_api_init' );
function salient_child_rest_api_init() {
register_rest_route(
'namespace/v1',
'/example',
[
'methods' => WP_REST_Server::CREATABLE,
'callback' => 'salient_child_process_example_endpoint',
]
);
}
function salient_child_process_example_endpoint() {
// your logic ...
$data = [
'pid' => 1
]; // example data for testing if it is working
return new WP_REST_Response( $data, 200 );
}
And change your jQuery.post with this
jQuery.post(
{
url: `${document.location.origin}/wp-json/namespace/v1/example`,
data: {
'action': 'do_ts_woo',
'order': orderfilename,
'tilesize': globalTileSize,
'board': urlAtts,
'table': table
},
xhrFields: {
withCredentials: true
}
})
.done(function (data) {
const pid = data.pid;
if (pid > 0) {
console.log("do_ts_woo. SUCCESS response=" + pid);
alert('Add to cart: ' + response.id);
ts_iframe(shopdomain + "/cart/?add-to-cart=" + pid);
} else {
console.log("do_ts_woo. FAILURE response=" + response.id);
}
return false;
})
.fail(function (msg) {
alert("error msg=" + msg);
})
.always(function (response) {
});
If not - maybe there are PHP warnings modifying your response output with enexpected messages and breaking your response data.

Kohana with AJAX get request

I am new to the world of Kohana/php and am having some issues understanding how to get the result of an ajax request. This request is being called from a click action and is invoking the following method.
function addClickHandlerAjax(marker, l){
google.maps.event.addListener(marker, "click",function(){
console.log(l.facilityId);
removeInfoWindow();
//get content via ajax
$.ajax({
url: 'map/getInfoWindow',
type: 'get',
data: {'facilityID': l.facilityId },
success: function(data, status) {
if(data == "ok") {
console.log('ok');
}
},
error: function(xhr, desc, err) {
console.log(xhr);
console.log("Details: " + desc + "\nError:" + err);
}
}); // end ajax call
});
}
Inside of my controller I have a method
public function action_getInfoWindow(){
if ($this->request->current()->method() === HTTP_Request::GET) {
$data = array(
'facility' => 'derp',
);
// JSON response
$this->auto_render = false;
$this->request->response = json_encode($data);
}
}
I see an HTTP request in fiddler and it passed the correct facilityID parameter. However I am having some disconnect about how to connect all the pieces together.
To send a response to the browser, you should user Controller::response instead of Controller::request::response. So your code should look like this:
public function action_getInfoWindow() {
// retrieve data
$this->response->body(json_encode($data));
}
That should give you some output.
Checkout the Documentation for more detailed info.
Edit
What you could do, to make your life a bit easier, especially if you gonna use ajax requests a lot, is to create an Ajax controller. You can stuff all checks and transforms in it, and never worry about it anymore. An example controller could look like below. Also checkout the Controller_Template which is shipped as an example by Kohana.
class Controller_Ajax extends Controller {
function before() {
if( ! $this->request->is_ajax() ) {
throw Kohana_Exception::factory(500, 'Expecting an Ajax request');
}
}
private $_content;
function content($content = null) {
if( is_null( $content ) ) {
return $this->_content;
}
$this->_content = $content;
}
function after() {
$this->response->body( json_encode( $this->_content ) );
}
}
// example usage
class Controller_Home extends Controller_Ajax {
public function action_getInfoWindow() {
// retrieve the data
$this->content( $data );
}
}

Categories