Error handling for ajax call from jquery jtable - javascript

I have a jtable that has a listAction that calls an action in the controller to return the data for the table. If the user refreshes the page while the action is in progress its alerts:
Here is the jtable:
$('#cuserTable').jtable({
title: 'Users',
paging: true,
pageSize: 15,
sorting: true,
ajaxSettings: {
contentType: 'application/json'
},
actions: {
listAction: '#Url.Action("LoadUserTable")'
},
.
.
How and where can I add an error handler to display a custom alert (or not even display an alert) if the user refreshes during a table load/reload?

you can handle the error messages for the dialog:
Imagine you are performing an update and you want to return to the dialog message the error occurred:
try{
//UPDATING
[...]
Your update code goes here
[...]
$jTableResult = array();
$jTableResult['Result'] = "OK";
echo json_encoded($jTableResult);
}catch(Exception $ex){
$jTableResult = array();
$jTableResult['Result'] = "NOK";
$jTableResult['Message'] = "Error while updating the record XYZ";
echo json_encoded($jTableResult);
}

The response should have
data = {
Message : "error message",
Result : "ERROR"
};
$dfd.resolve(data);
In jquery jtable, you have to do $dfd.resolve(data)

Related

Handling a Stripe customer creation error client side

I've been using Stripe to successfully process payments. The payment intent is created in PHP on the server and there is client side scripting in javascript to set up and call the payment intent script and handle the results.
If something like a card declined happens, then this is handled fine. However if there is a different kind of problem then although I can successfully trap this error server side, I've been unable to work out how to handle it client side and display a useful error message to the user.
This is my client side code:
var stripe = "***HIDDEN***";
var stripesetup = "/stripecreate.php";
var subscriptionid = document.getElementById("subscriptionid").value;
var email = document.getElementById('email').value;
// The items the customer wants to buy
var purchase = {
items: [{ id: subscriptionid }]
};
// Disable the button until we have Stripe set up on the page
document.getElementById("btn-checkout").disabled = true;
fetch(stripesetup, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(purchase)
}).then(function(result) {
/* This is where the error should be trapped, however result isn't the value from the server side script */
return result.json();
}).catch( (message) => {
/* Have also been trying to handle 'message' in here but without success */
}).then(function(data) {
var elements = stripe.elements();
var style = {
base: {
color: "#32325d",
fontFamily: 'Arial, sans-serif',
fontSmoothing: "antialiased",
fontSize: "16px",
"::placeholder": {
color: "#32325d"
}
},
invalid: {
fontFamily: 'Arial, sans-serif',
color: "#fa755a",
iconColor: "#fa755a"
}
};
// Stripe injects an iframe into the DOM
var card = elements.create("card", { style: style });
card.mount("#card-element");
/*
var cardNumberElement = elements.create('cardNumber');
cardNumberElement.mount("#card-element");
var cardExpiryElement = elements.create('cardExpiry');
cardExpiryElement.mount("#cardexpiry-element");
*/
card.on("change", function (event) {
// Disable the Pay button if there are no card details in the Element
document.getElementById("btn-checkout").disabled = event.empty;
document.querySelector("#shopvalidation").textContent = event.error ? event.error.message : "";
});
var form = document.getElementById("shopform5");
form.addEventListener("submit", function(event) {
event.preventDefault();
// Complete payment when the submit button is clicked
payWithCard(stripe, card, data.clientSecret);
});
});
// Calls stripe.confirmCardPayment
// If the card requires authentication Stripe shows a pop-up modal to
// prompt the user to enter authentication details without leaving your page.
var payWithCard = function(stripe, card, clientSecret) {
loading(true);
stripe
.confirmCardPayment(clientSecret, {
receipt_email: email,
payment_method: {
card: card
}
})
.then(function(result) {
if (result.error) {
// Show error to your customer
showError(result.error.message);
} else {
// The payment succeeded!
orderComplete(result.paymentIntent.id);
}
});
};
/* ------- UI helpers ------- */
// Shows a success message when the payment is complete
var orderComplete = function(paymentIntentId) {
loading(false);
document.getElementById("btn-checkout").disabled = true;
location.href="/thank-you";
};
// Show the customer the error from Stripe if their card fails to charge
var showError = function(errorMsgText) {
loading(false);
var errorMsg = document.querySelector("#shopvalidation");
errorMsg.textContent = "Unfortunately your payment has been unsuccessful due to "+errorMsgText+" Please contact us for more information";
setTimeout(function() {
errorMsg.textContent = "";
}, 10000);
};
// Show a spinner on payment submission
var loading = function(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.getElementById("btn-checkout").disabled = true;
document.querySelector("#lds-ring").classList.remove("invisible");
document.querySelector("#button-text").classList.add("invisible");
} else {
document.getElementById("btn-checkout").disabled = false;
document.querySelector("#lds-ring").classList.add("invisible");
document.querySelector("#button-text").classList.remove("invisible");
}
};
On the server, the payment intent is being created with this:
try {
$customer = \Stripe\Customer::create([
'name' => $fullname,
'email' => $email,
'phone' => $telephone,
"shipping" => [
'name' => $fullname,
"address" => [
"line1" => $address1,
"line2" => $address2,
"city" => $town,
"state" => $county,
"country" => $countrycode
],
],
"address" => [
"line1" => $billingaddress1,
"line2" => $billingaddress2,
"city" => $billingtown,
"state" => $billingcounty,
"country" => $billingcountrycode
],
'description' => $userid
]);
$stripeid = $customer->id;
} catch(\Stripe\Exception\CardException $e) {
// Since it's a decline, \Stripe\Exception\CardException will be caught
echo 'Status is:' . $e->getHttpStatus() . '\n';
echo 'Type is:' . $e->getError()->type . '\n';
echo 'Code is:' . $e->getError()->code . '\n';
echo 'Param is:' . $e->getError()->param . '\n';
echo 'Message is:' . $e->getError()->message . '\n';
die();
} catch (\Stripe\Exception\RateLimitException $e) {
// Too many requests made to the API too quickly
echo json_encode(['error' => $e->getMessage()]);
die();
} catch (\Stripe\Exception\InvalidRequestException $e) {
// Invalid parameters were supplied to Stripe's API
echo json_encode(['error' => $e->getMessage()]);
die();
} catch (\Stripe\Exception\AuthenticationException $e) {
// Authentication with Stripe's API failed
// (maybe you changed API keys recently)
echo json_encode(['error' => $e->getMessage()]);
die();
} catch (\Stripe\Exception\ApiConnectionException $e) {
// Network communication with Stripe failed
echo json_encode(['error' => $e->getMessage()]);
die();
} catch (\Stripe\Exception\ApiErrorException $e) {
// Display a very generic error to the user, and maybe send
// yourself an email
echo json_encode(['error' => $e->getMessage()]);
die();
} catch (Exception $e) {
// Something else happened, completely unrelated to Stripe
echo json_encode(['error' => $e->getMessage()]);
die();
}
}
An "\Stripe\Exception\InvalidRequestException" is being thrown in my testing when I delibrately put in an invalid phone number. This is being returned by my stripecreate.php script:
{"error":"Invalid string: 0123456789...0123456789; must be at most 20 characters"}
I would expect this to be handled in the first part of the promise indicated in my client side script above, however the result is returning this when echoed to the console:
Response { type: "basic", url: "https://www.HIDDEN*****/stripecreate.php", redirected: false, status: 200, ok: true, statusText: "OK", headers: Headers(11), body: ReadableStream, bodyUsed: false }
​
body: ReadableStream { locked: true }
​
bodyUsed: true
​
headers: Headers(11) { "cache-control" → "no-store, no-cache, must-revalidate", "content-length" → "82", "content-type" → "application/json", … }
​
ok: true
​
redirected: false
​
status: 200
​
statusText: "OK"
​
type: "basic"
​
url: "https://www.HIDDEN*****/stripecreate.php"
​
<prototype>: ResponsePrototype { clone: clone(), arrayBuffer: arrayBuffer(), blob: blob(), … }
I expect this is me not correctly understanding how the promise structure is working and how I can get the response text from the server so I can check for an error and display it.
The next .then in the promise carries on execution even though I want it to stop at that point.
Been scratching my head over this one all day. Any help gratefully received.
Seems like your server is responding with JSON & 200 status code, so the first .then() callback only parses the response and moves on.
The status of the response being 200, it is unlikely that it'll be caught by the .catch() function too.
So you'd likely want to handle this response in the following .then() call.
Have you tried responding with a different response code (4xx) or (5xx) to see if that triggers .catch() callback?

PayPal Smart Payment Buttons: Error: JSON.parse: unexpected character at line 1 column 1 of the JSON data

I've been trying to figure out this problem for 2 days already..
I want to implement Smart Payment Buttons from PayPal, literally followed every step of the explanation closely but still getting following error:
Error: JSON.parse: unexpected character at line 1 column 1 of the JSON data
My javascript for Button rendering:
paypal.Buttons({
createOrder: function() {
return fetch('vendor/paypal/paypal-checkout-sdk/samples/CaptureIntentExamples/CreateOrder.php', {
method: 'post',
headers: {
'content-type': 'application/json'
}
}).then(function(res) {
return res.json();
}).then(function(data) {
return data.orderID; // Use the same key name for order ID on the client and server
});
},
onApprove: function(data, actions) {
// This function captures the funds from the transaction.
return actions.order.capture().then(function(details) {
// This function shows a transaction success message to your buyer.
alert('Transaction completed by ' + details.payer.name.given_name);
});
},
onError: function(err) {
alert(err);
}
}).render('#paypal-button-container');
My CreateOrder.php:
namespace Sample\CaptureIntentExamples;
require __DIR__ . '/../../../../autoload.php';
use Sample\PayPalClient;
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
class CreateOrder
{
/**
* Setting up the JSON request body for creating the Order. The Intent in the
* request body should be set as "CAPTURE" for capture intent flow.
*
*/
private static function buildRequestBody()
{
return array(
'intent' => 'CAPTURE',
'application_context' =>
array(
'return_url' => 'https://example.com/return',
'cancel_url' => 'https://example.com/cancel'
),
'purchase_units' =>
array(
0 =>
array(
'amount' =>
array(
'currency_code' => 'USD',
'value' => '220.00'
)
)
)
);
}
/**
* This is the sample function which can be sued to create an order. It uses the
* JSON body returned by buildRequestBody() to create an new Order.
*/
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->headers["prefer"] = "return=representation";
$request->body = self::buildRequestBody();
$client = PayPalClient::client();
$response = $client->execute($request);
if ($debug)
{
print "Status Code: {$response->statusCode}\n";
print "Status: {$response->result->status}\n";
print "Order ID: {$response->result->id}\n";
print "Intent: {$response->result->intent}\n";
print "Links:\n";
foreach($response->result->links as $link)
{
print "\t{$link->rel}: {$link->href}\tCall Type: {$link->method}\n";
}
// To toggle printing the whole response body comment/uncomment below line
echo json_encode($response->result, JSON_PRETTY_PRINT), "\n";
}
return $response;
}
}
if (!count(debug_backtrace()))
{
CreateOrder::createOrder(true);
}
It's basicly all copied from the PayPal walkthough.
If I visit the CreateOrder.php directly it is creating an order and I can see the response without errors.
Status Code: 201 Status: CREATED [...]
What I did was deleting the part of the code which was printing out the response in txt format. This is why you were getting JSON syntax error.
public static function createOrder($debug=false)
{
$request = new OrdersCreateRequest();
$request->prefer('return=representation');
$request->body = self::buildRequestBody();
// 3. Call PayPal to set up a transaction
$client = PayPalClient::client();
$response = $client->execute($request);
// To print the whole response body, uncomment the following line
echo json_encode($response->result, JSON_PRETTY_PRINT);
// 4. Return a successful response to the client.
return $response;
}
By the way, this answer is very helpful: https://stackoverflow.com/a/63019280/12208549

Why isn't jQuery Post sending any data?

I am trying to use Instafeed to show my Instagram feed on my website. However, I do not want to run it everytime someone accesses my website, so I'm trying to write the response to a file. For that I am using the following code
var userFeed = new Instafeed({
get: 'user',
userId: 'xxx',
accessToken: 'xxx',
sortBy: 'most-recent',
limit: '12',
template: '<img src="{{image}}" title="{{caption}}"/>',
link: 'true',
success: function(response) {
console.log(response.data);
$.post('saveInstagram.php', {list: response.data}, function(o) {
console.log(o);
}, 'json');
}
});
userFeed.run();
saveInstagram.php (very basic, just to test)
$list = $_POST['list'];
$myfile = fopen("instagramFeed.html", "w") or die("Unable to open file!");
fwrite($myfile, $list);
fclose($myfile);
The console log shows the correct data which should get sent to saveInstagram.php. The response isn't being sent however. I tried changing the value manually to {list: 'test'} in order to check the save-script, and that works, 'test' is being written to the file. So I don't seem to understand why response.data isn't being sent by the script, but does show up in the console.log. Thank you in advance!

Semantic-UI search does not read JSON from server response

I'm currently using Semantic-UI in a project. I use the search module to get the results from input. Here's my JavaScript code:
$('.ui.search')
.search({
apiSettings: {
action: 'search',
url: 'process.php?q={query}',
onSuccess(response, element, xhr){
console.log(response);
}
},
fields: {
results: 'songs', // array of results (standard)
title: 'title', // result title
url: 'videoID'
},
showNoResults: true,
onResults(response) {
console.log(response);
}
})
;
I get the JSON response from process.php. Here it is:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
header("Content-Type: application/json; charset=UTF-8");
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new \Exception('please run "composer require google/apiclient:~2.0" in "' . __DIR__ .'"');
}
require_once __DIR__ . '/vendor/autoload.php';
// This code will execute if the user entered a search query in the form
// and submitted the form. Otherwise, the page displays the form above.
$videos = array();
// $videos["action"]["url"] = "youtube.com";
if (isset($_GET['q'])) {
/*
* Set $DEVELOPER_KEY to the "API key" value from the "Access" tab of the
* {{ Google Cloud Console }} <{{ https://cloud.google.com/console }}>
* Please ensure that you have enabled the YouTube Data API for your project.
*/
$DEVELOPER_KEY = 'MY_API_KEY';
$client = new Google_Client();
$client->setDeveloperKey($DEVELOPER_KEY);
// Define an object that will be used to make all API requests.
$youtube = new Google_Service_YouTube($client);
try {
// Call the search.list method to retrieve results matching the specified
// query term.
$searchResponse = $youtube->search->listSearch('id,snippet', array(
'q' => $_GET['q'],
'maxResults' => 2
));
// Add each result to the appropriate list, and then display the lists of
// matching videos, channels, and playlists.
foreach ($searchResponse['items'] as $searchResult) {
switch ($searchResult['id']['kind']) {
case 'youtube#video':
$videos["songs"][] = array('title' => $searchResult['snippet']['title'], 'videoID' => $searchResult["id"]["videoId"]);
break;
}
}
} catch (Google_Service_Exception $e) {
die($e->getMessage());
}
}
echo json_encode($videos);
The problem is that once I start typing in the search input, nothing shows up, even though my JSON structure is valid. I have assigned the Semantic UI properties correctly. I'm following the standard JSON response that Semantic UI has suggested. Here's my JSON response
{
"songs":[
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth [Official Video] Furious 7 Soundtrack",
"videoID":"RgKAFK5djSk"
},
{
"title":"Wiz Khalifa - See You Again ft. Charlie Puth (MattyBRaps ft Carissa Adee Cover)",
"videoID":"Rpm8ZJuGEu4"
}
]
}
I've tried everything. It doesn't work. I would really appreciate your help

Pass an argument on event change using http post request

I'm using the bootstrap ON/OFF switches to send an http post request on the event change. Whenever a switch changes its state from ON to OFF or OFF to ON, an http post request is triggered. Yes, it is working. However, I am not sure how to pass an argument through the http post function ($.post).
The update_state.php file takes in the argument 'state'. For example, update_state.php?state=ON will change the value of state field in the database.
The code I have so far.
<script type="text/javascript">
$('input[name="onoffswitch"]').on('switchChange.bootstrapSwitch', function(event, state) {
console.log(state); // true | false
$.post("update_state.php",
{
state: "state"
},
function(data, status){
console.log("Data: " + data + "\nStatus: " + status);
});
});
</script>
EDIT:
<?php
require_once("mysqli_connect.php");
if (!$database) {
echo "Error: Unable to connect to MySQL." . PHP_EOL;
exit;
}
echo "Success: A proper connection to MySQL was made!" . PHP_EOL;
$state = $_GET['state'];
$sql = "UPDATE devices SET state='$state' WHERE id=1";
if (mysqli_query($database, $sql)) {
echo "Record updated successfully.";
} else {
echo "Error updating record: " . mysqli_error($database);
}
mysqli_close($database);
?>
Try:
$('input[name="onoffswitch"]').on('switchChange.bootstrapSwitch', function(event, state) {
console.log(state); // true | false
$.post( "update_state.php", { state: state }) // here { state: state } means {parameter-name: parameter-value}
.done(function( data ) {
alert( "Data Loaded: " + data );
});
});

Categories

Resources