October 9, 2017

WordPress AJAX Call Using Axios.js

I have been working on a project since the past few days. The user interface of the project has been built using Vue.js framework. The project required retrieving data for rendering using AJAX calls. After going through the Vue 2.0 AJAX Call Forum discussions and careful consideration, I decided to replace the jQuery AJAX calls from my project code and use axios.js instead.

The Problem

Post the code switch, the response I got from axios AJAX call was ‘0’. The old code in jQuery used to give me a name array in json format.

Note: The following code is a mock-up of this scenario. The actual code from the project isn’t included.

Function that returns a random generated name array as JSON response to AJAX call:


<?php

function returnRandomNames()
{
    $names = array( "Tom", "Bat", "Tim", "Swag", "Rat", "Cat", "Boot", "Dota" );
    shuffle($names);
    $rand_names = array_slice($names, 0, rand(1, 8));
    wp_send_json($rand_names);
}
add_action('wp_ajax_nopriv_get_names', 'returnRandomNames');
add_action('wp_ajax_get_names', 'returnRandomNames');

The intiall AJAX call using jQuery :


var data = { action: 'get_names', key2:'value2' ...... };

jQuery.post('/wp-admin/admin-ajax.php', data )
.done( function (response) {
    console.log(response);
})
.fail( function (error) {
    console.log(error);
});

The updated AJAX call using axios :


var data = { action: 'get_names', key2:'value2' ...... }; 

axios.post('/wp-admin/admin-ajax.php', data )
.then( function (response) {
    console.log(response.data);
})
.catch( function (error) {
    console.log(error);
});

The above jQuery code will return an array of random names and axios code will return ‘0’.

The Debug

jQuery sends javascript objects as post data in the application/x-www-form-urlencoded format. On the other hand axios serializes javascript objects to JSON by default.

This makes it impossible for WordPress to decode the AJAX syntax to get ‘action’ data and it breaks on the following line of wp-admin/admin-ajax.php : line 27


// Require an action parameter
if ( empty( $_REQUEST['action'] ) )
die( '0' );

The Fix

In order to fix this issue, you need to send the data in application/x-www-form-urlencoded format. We can achieve this in two known ways.

1. Using URLSearchParams API :


var params = new URLSearchParams();
params.append('action', 'get_names');
// params.append('key2', 'value2');
// params.append('key3', 'value3');
axios.post('/wp-admin/admin-ajax.php', params )
.then( function (response) {
    console.log(response.data);
})
.catch( function (error) {
    console.log(error);
});

Note: URLSearchParams is not supported by all of the browsers ( check caniuse for URLSearchParams ).

2. The better way is to use query string library qs.js to encode the data before sending them. You need to enqueue qs.js before your main script.


var data = { action: 'get_names', key2:'value2' ...... }; 

axios.post('/wp-admin/admin-ajax.php', Qs.stringify( data ))
.then( function (response) {
    console.log(data);
})
.catch(function (error) {
    console.log(error);
});

The GitHub

I have created a demo plugin to demonstrate this and added it to my Github repo (kt-12/wordpress-axios-ajax).

2 thoughts on “WordPress AJAX Call Using Axios.js

Leave a Reply

Your email address will not be published. Required fields are marked *