1

I am working on a project where i must call a 3rd party API from client-side then process the response in PHP before displaying it in on the front end. So i planned it in my head like this:

  1. use getJSON to call the 3rd party API
  2. send response to PHP via AJAX
  3. put it in a variable and use it

Unfortunately i can't figure out how to put the response in a php variable and use it in my shortcode function.I am not a PRO developer, but in the last two days i've read anything related to this situation, so here is my current code:

The external API url supports params and i am constructing it depending what i need on the particular page, using shortcode atts. So the journey starts in add_shortcode callback function:

$url = theAPIurl //with parameters
$apinonce = wp_create_nonce('apinonce');
wp_add_inline_script('ajax-request', 'const apidata = '.json_encode( array( 'apiUrl' => $url , 'ajaxUrl' => admin_url( 'admin-ajax.php' ) , 'nonce' => $apinonce  )) , 'before');

The enqueued scripts:

wp_register_script('ajax-request' , 'pathtomyjs' , array('jquery'), false, true);
wp_enqueue_script('ajax-request');

My JS file

$.getJSON(apidata.apiUrl , function(response_data){
        $.ajax({
          type: 'POST',
          url: apidata.ajaxUrl,
          data: {nonce: apidata.apinonce, action:'api_response', data:JSON.stringify(response_data) },
          dataType:"json"
        });
        return false;   
  })

AJAX action hooks

add_action('wp_ajax_api_response' , 'kwpca_api_callback' );
add_action('wp_ajax_nopriv_api_response' , 'kwpca_api_callback' );

AJAX callback function

function kwpca_api_callback() {
        check_ajax_referer('apinonce' , 'nonce');
        $response = json_decode(stripslashes($_POST["data"]), true);
        $data = wp_send_json($response);
}

Looking in browser dev tools->network, i can see both getJSON and admin-ajax requests being successful, the data is what i need, but i can't figure out how to pass it to my shortcode function.

If i call the function directly like $newdata = kwpca_api_callback(), and var_dump($newdata), the output is -1 and no ajax calls are executed in network tab. At this point i'm clueless what to do next and i lost count how many times i've reverted the code trying possible solutions. Any help is very much appreciated

2
  • 1
    Is there a reason to not use wp_safe_remote_get() or wp_safe_remote_post() to get the data from the API? It seems to me like you're adding unnecessary layers here—starting on the server side (the shortcode), moving to AJAX for the request, then trying to deliver the data from AJAX back to the server side for output.
    – Pat J
    Commented Jan 15, 2023 at 19:22
  • 1
    @PatJ The API is throttled and needs the client IP for geo filtering. My first approach was to use wp_remote_get() but there were times when the response was not the expected data, but a message that the request limit has been reached. Also, the developers said that doing it server side, will always use the server IP, regardless of the arguments passed. Thanks for looking
    – k33n
    Commented Jan 15, 2023 at 20:06

1 Answer 1

2

After more reading and testing, i've realised that i misunderstood how AJAX works, therefore it was never gonna work the way i thought it would. For those who come across this, i hope this will help.

In shortcode function i generated the api url with params specific to the page where shortcode is called. eg [my_shortcode list="employees" type="json" sort="DESC"].

I used wp_add_inline_script() to send data from PHP to my custom JS. Added an empty div with unique id, for AJAX to insert my HTML

my_shortcode_callback($atts) {
    $atts= shortcode_atts( array(
        /* params for constructing API url to be called */
    ), $atts);
    $apiUrl = 'https://somedomain.xyz/?list=employees&type=json&sort=desc';
    /*Pass the api url, ajax url and nonce to the js file. 
     The recommended way but wp_localize_script works too */
    wp_add_inline_script('ajax-request', 'const apidata = '.json_encode( array( 'apiUrl' => $apiUrl , 'ajaxUrl' => admin_url( 'admin-ajax.php' ) , 'nonce' => wp_create_nonce('apinonce)  )) , 'before');
    $html = '<div id="ajax-html"></div>';
    return $html;
} 

The enqueued scripts:

wp_register_script('ajax-request' , 'pathtomyjs' , array('jquery'), false, true);
wp_enqueue_script('ajax-request');

My JS file

The below code is calling the 3rd party API then send the response to the server via AJAX POST. On success, will insert server response in <div id="ajax-html"></div>

$.getJSON(apidata.apiUrl , function(response_data){
    $.ajax({
        type: 'POST',
        url: apidata.ajaxUrl,
        data: {nonce: apidata.apinonce, action:'api_response', data:JSON.stringify(response_data) },
        dataType:"json",
        cache:false,
        success: function( response ){
            $('#ajax-html').html(response['data'])
        },
        error: function( error ){
            console.log('AJAX error callback....');
            console.log(error);
        }
    });
})

AJAX action hooks

add_action('wp_ajax_api_response' , 'kwpca_api_callback' );
add_action('wp_ajax_nopriv_api_response' , 'kwpca_api_callback' );

AJAX callback function

function kwpca_api_callback() {
  check_ajax_referer('apinonce' , 'nonce');
  if(isset($_POST['data'])){
    $response = json_decode(stripslashes($_POST['data']), true);
    // process received data in PHP. EG:
    $html = '<ul>';
    foreach($response as $data){
      $html .= '<li>'.$data['title'].'</li>';
    }
    $html .= '</ul>' 
  } 
  $data = wp_send_json_success($html);
}

HTML Output

<div id="ajax-html">
  <ul>
    <li>Title1</li>
    <li>Title2</li>
    <li>Title3</li>
    <li>etc...</li>
  </ul>
</div>

The above is a stripped version of my code to show how to get data from an external api using AJAX then create shortcode to display received data. I hope it will help somebody.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.