Netty Admin
asked on
Wordpress - Javascript - JQuery - AJAX - Need assistance with creating error handling for a Jquery script
Need to add some error handling to the following set of functions:
this is the function.php file
The problem is that sometimes the response comes back with no secureURL property...At this moment I would like it to display a message that says "Please Try Again" so the user knows to click the button again
Annotation-2020-06-30-104947.png
Annotation-2020-06-30-105100.png
Annotation-2020-06-30-105257.png
jQuery( function( $ ) {
$(document).ready( function() {
/**
* AJAX Call to grab the Order URL from the server via the custom url created in Azure logics
*/
$( document.body ).on( "click", "#payment #get_cc_order_url.get_cc_order_url", function(e) {
e.preventDefault();
$.ajax({
url : ccOrderParams.url,
data : {
action : 'get_order_url',
security : ccOrderParams.nonce,
},
type : 'post',
beforeSend: function() {
// spinner and please wait code here
let pleaseWait = `
<div id="pleasewait" style="text-align:center">
<br><br><p>Retrieving Secure Window</p>
<img src="path/to/gif"
style="display:inline-block">
</div>
`
$('#cc_card_iframe').before(pleaseWait)
},
}).done(function(response) {
// remove the please wait message
$('#pleasewait').remove()
$('#cc_card_iframe').prop('src', response.data.secureURL)
}).fail(function(error) {
console.log("ERROR", error)
})
});
});
})
/**
*
* Validates if card is inputted and then displays success message and unhides the place order button and if the trasaction is canceled
* Also if the trasaction is canceled it displays a Credit Card Not Saved message
*/
jQuery( function( $ ) {
$(document).ready( function() {
$(window).on('message', function(e) {
console.log("MESSAGE DATA", e)
if (e.originalEvent.origin !== "https://api-east.pestpac.com")
return;
let ccInfo = JSON.parse(e.originalEvent.data)
if (ccInfo.BillToID) {
$('#cc_card_iframe').hide().after(`<br><br><br><p>Credit Card Saved Successfully<br><br><br></p>`)
$("#payment #place_order.button.alt").fadeIn('slow')
} else if (ccInfo.Error) {
$('#cc_card_iframe').hide().after(`<br><br><br><p>Credit Card Not Saved<br><br><br></p>`)
}
});
});
})
this is the function.php file
<?php
/*
* Custom PHP code for child theme will be here
*/
/**
* the AJAX handler
*/
add_action('wp_ajax_get_order_url', 'get_order_url');
function get_order_url()
{
check_ajax_referer('security_matters', 'security');
$user = get_user_data();
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'azure_url',
CURLOPT_TIMEOUT => 0,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => json_encode($user),
CURLOPT_HTTPHEADER => ['Content-Type:application/json'],
]);
$response = curl_exec($curl);
if (!curl_errno($curl)) {
wp_send_json_success(json_decode($response));
} else {
$response = ['error' => curl_error($curl)];
wp_send_json_error($response);
}
}
/**
* Get the User data
*/
function get_user_data() : array
{
$user = wp_get_current_user();
$data = [
'UserId' => $user->ID,
'Email' => $user->user_email,
'Username' => $user->user_login,
];
return $data;
}
/*
* Enqueue scripts for cc button on checkout page
*/
add_action( 'wp_enqueue_scripts', 'setup_order_scripts', 15 );
function setup_order_scripts() {
$params = [
'url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('security_matters'),
];
wp_register_script( 'cc_order_scripts', get_stylesheet_directory_uri() . '/order-scripts.js', array('jquery'), null, true);
wp_localize_script( 'cc_order_scripts', 'ccOrderParams', $params);
wp_enqueue_script( 'cc_order_scripts' );
}
/** Adding child theme's style.css **/
function tm_fixology_child_style_css(){
wp_enqueue_style( 'fixology-child-style', get_stylesheet_directory_uri() . '/style.css' );
}
add_action( 'wp_enqueue_scripts', 'tm_fixology_child_style_css', 18 );
// Disable auto-complete on form.
add_filter( 'gform_form_tag', function( $form_tag ) {
return str_replace( '>', ' autocomplete="off">', $form_tag );
}, 11 );
// Diable auto-complete on each field.
add_filter( 'gform_field_content', function( $input ) {
return preg_replace( '/<(input|textarea)/', '<${1} autocomplete="off" ', $input );
}, 11 );
The problem is that sometimes the response comes back with no secureURL property...At this moment I would like it to display a message that says "Please Try Again" so the user knows to click the button again
Annotation-2020-06-30-104947.png
Annotation-2020-06-30-105100.png
Annotation-2020-06-30-105257.png
ASKER
^^^^^^updated the question ^^^^
Hey Netty,
You have a couple of options here, depending on what data does come back from the API call. My preference would be to handle the logic in the PHP file. If you look at that we have this:
You have a couple of options here, depending on what data does come back from the API call. My preference would be to handle the logic in the PHP file. If you look at that we have this:
if (!curl_errno($curl)) {
wp_send_json_success(json_decode($response));
} else {
$response = ['error' => curl_error($curl)];
wp_send_json_error($response);
}
When call wp_send_json_success(), the AJAX response receives a success:true property. When we call wp_send_json_error(), the AJAX response receive a success:false property, so in your AJAX handler, you can do this:}).done(function(response) {
// remove the please wait message
$('#pleasewait').remove()
if (response.success) {
// we have the secureUrl
$('#cc_card_iframe').prop('src', response.data.secureURL)
} else {
// we don't have the secureUrl
// code your error message here
}
})
You now just need to add your logic into the PHP file to make sure you have actually received a secureUrl - if you have use wp_send_json_success(), if you haven't use wp_send_json_error().
ASKER
Thank you Chris,
I put it in place but have not had it hit on it yet. Once I get an error and see the message display I will report back on here..
I put it in place but have not had it hit on it yet. Once I get an error and see the message display I will report back on here..
ASKER
It does not seem to display the "Please Try Again" message when there is an error. I spoke with my coworker about it and he said he can have it send me a JSON response for all errors, we agreed on the JSON property {URL_error=""}......I do not know exactly how he is setting this to be the catch-all response for all errors but I think that is what he now has setup. Strange though, because even though there are times when I am not receiving the secureURL property it does not seem to display the message, unless he is still sending me that property and it is empty and that is why.
Now when he sends the URL_error it may indeed be empty in some cases but he says I will at least get that property back so maybe we could add a line or two to cover this condition as well.
Now when he sends the URL_error it may indeed be empty in some cases but he says I will at least get that property back so maybe we could add a line or two to cover this condition as well.
ASKER
So what we have already set up will cover instances when we do not get back a JSON success response from the request, which is great but now we want also include the condition when we do receive a response but instead of it being secureURL it will be URL_error
And his script is coded to send back this URL_error to mine if his script gets either 200, 400, 500, etc. errors on his call for the URL
And his script is coded to send back this URL_error to mine if his script gets either 200, 400, 500, etc. errors on his call for the URL
ASKER
Also for the method you first suggested for the wp_send_json_error
Since we already are hiding the iframe before and/or it is not showed yet, I would need to create another element to select in order to display the message in the follow error you showed above, where you have "code your message here" correct?
Or can I still select the iframe and hide it even though it may have already been hidden, this could still work, right?
Since we already are hiding the iframe before and/or it is not showed yet, I would need to create another element to select in order to display the message in the follow error you showed above, where you have "code your message here" correct?
Or can I still select the iframe and hide it even though it may have already been hidden, this could still work, right?
$('#cc_status_canceled').hide()
$('#cc_status_success').hide()
$('#cc_card_iframe').hide().before(pleaseWait)
},
}).done(function(response) {
// removes the please wait message
$('#pleasewait').remove()
console.log(response)
if (response.success) {
// we have a successful JSON response from the Azure Logic Script
$('#cc_card_iframe').prop('src', response.data.secureURL).show()
} else {
// we do not have a successful JSON response from the Azure Logic Script
$('#cc_card_iframe').hide().after('<br><br><p>Please Try Again</p>')
}
ASKER
Or maybe it would be best to do it like this
if (response.data.secureURL) {
//we have a successful JSON Secure URL response from the Azure Logic Script
$('#cc_card_iframe').prop('src', response.data.secureURL).show()
} else if (response.data.URL_error){
// we have as successful response from the Azure Logic Script but with an error message forwarded from the parent call to worldpay
$('#cc_card_iframe').after('<br><br><p>Please Try Again</p>')
} else {
console.log("Error No JSON Data Returned")
$('#cc_card_iframe').after('<br><br><p>Please Try Again</p>')
}
And since the beforeSend function hides the iframe already I would remove the .hide() from those lines like I did. ^^^This should accomplish my goals, correct?ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
<?php
/*
* Custom PHP code for child theme will be here
*/
/**
* the AJAX handler
*/
add_action('wp_ajax_get_order_url', 'get_order_url');
function get_order_url()
{
check_ajax_referer('security_matters', 'security');
$user = get_user_data();
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => 'CustomURL',
CURLOPT_TIMEOUT => 0,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => json_encode($user),
CURLOPT_HTTPHEADER => ['Content-Type:application/json'],
]);
$response = curl_exec($curl);
$response_data = json_decode($response);
if (isset($response_data['secureUrl'])) {
wp_send_json_success($response_data);
} else {
wp_send_json_error($response_data);
}
/**
* if (!curl_errno($curl)) {
*
* wp_send_json_success(json_decode($response));
*
* } else {
*
* $response = ['error' => curl_error($curl)];
*
* wp_send_json_error($response);
*
* }
*/
}
/**
* Get the User data
*/
function get_user_data() : array
{
$user = wp_get_current_user();
$data = [
'UserId' => $user->ID,
'Email' => $user->user_email,
'Username' => $user->user_login,
];
return $data;
}
/*
* Enqueue scripts for cc button on checkout page
*/
add_action( 'wp_enqueue_scripts', 'setup_order_scripts', 15 );
function setup_order_scripts() {
$params = [
'url' => admin_url( 'admin-ajax.php' ),
'nonce' => wp_create_nonce('security_matters'),
];
wp_register_script( 'cc_order_scripts', get_stylesheet_directory_uri() . '/order-scripts.js', array('jquery'), null, true);
wp_localize_script( 'cc_order_scripts', 'ccOrderParams', $params);
wp_enqueue_script( 'cc_order_scripts' );
}
/** Adding child theme's style.css **/
function tm_fixology_child_style_css(){
wp_enqueue_style( 'fixology-child-style', get_stylesheet_directory_uri() . '/style.css' );
}
add_action( 'wp_enqueue_scripts', 'tm_fixology_child_style_css', 18 );
// Disable auto-complete on form.
add_filter( 'gform_form_tag', function( $form_tag ) {
return str_replace( '>', ' autocomplete="off">', $form_tag );
}, 11 );
// Diable auto-complete on each field.
add_filter( 'gform_field_content', function( $input ) {
return preg_replace( '/<(input|textarea)/', '<${1} autocomplete="off" ', $input );
}, 11 );
I changed $data to $response_data because to see if it would help because it was already defined in this file for the user data. Can the same variable name be defined in multiple functions within a single file? as long as they are in different functions? or do we need to change it like I did here? I know that is not solving the failing of the AJAX but another side learning piece for me...……..as far as the call failing every time now, it did shed light on the fact that I also needed to add the "Try Again" message to when it completely fails like it is doing now which I did so it says "Try Again" when this complete fail condition is met as well...…..but I think there is a syntax error or the code is not written right on the 'secureURL' parse of the response. Can you take a look and see what needs to be changed? Thank you
ASKER
Are you sure it would not be a good idea to do it how I presented above within the order_scripts.js file? I figure that way down the road I can parse other messages he sends me and create additional error handling if need be. This way in the future we can have people report to us what they are seeing in the console when there is certain errors sent to their browser. What do you think?
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ASKER
Nevermind, All good, Its Working!! me and my coworker have it coded secureURL with the URL in caps and I forgot to change it when copy/pasting.
Thank you so Much! Monday is launch day and when the execs are going to be testing it all. Crossing my fingers. This has been great and I have once again learned a lot.
Thank you so Much! Monday is launch day and when the execs are going to be testing it all. Crossing my fingers. This has been great and I have once again learned a lot.
Excellent work Netty. Good luck with the launch :)
ASKER
Always on point.
ASKER
^^That was my feedback, dont know why when on the mobile app it doesnt actually register and go to the testimonials. I am sure you could figure it out for them..... the mobile app on here has a few more bugs as well..speaking of mobile versions, I opened another question regarding resizing the iframe perfectly for mobile devices, please take a look if you get a chance
ASKER