I'm trying to figure out how I should call a REST API custom endpoint from the JS code of a plugin. Here is the PHP code of a sample plugin I've just written to show my issue. The filename is rest-api-sample.php
:
<?php
/**
* @link https://www.virtualbit.it
* @since 1.0.0
* @package Rest-API-Sample
*
* @wordpress-plugin
* Plugin Name: Rest API Sample
* Plugin URI: https://www.virtualbit.it/rest-api-sample
* Description: Just a code sample
* Version: 1.0.4
* Author: Lucio Crusca
* Author URI: https://www.virtualbit.it
* License: GPL-2.0+
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
* Text Domain: rest-api-sample
* Domain Path: /languages
*/
class IESRestEndpoint
{
private $namespace = "ies/v1";
public function __construct() {
add_action( 'rest_api_init', array($this, 'registerRoutes'));
add_action( 'wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
public function istermactive(WP_REST_Request $request) {
$result = true;
return $result; // this is my controller.
}
public function registerRoutes() {
register_rest_route( $this->namespace,
'/istermactive/',
array('methods' => 'GET',
'callback' => array($this, 'istermactive')
)
);
}
public function enqueue_scripts() {
$handle = "ies-rest-api";
$jsfileurl = plugin_dir_url( __FILE__ ) . '/ies.js';
wp_register_script($handle, $jsfileurl, array("underscore", "backbone", "wp-api"));
$local_data = array('apiRoot' => get_rest_url(), "namespace" => $this->namespace);
wp_localize_script($handle, "ies_rest", $local_data);
wp_enqueue_script($handle);
}
}
$ies_endpoint = new IESRestEndpoint();
And here is the ies.js
code:
(function( $ ) {
'use strict';
$(document).ready(function()
{
wp.api.init({'versionString' : ies_rest.namespace, 'apiRoot': ies_rest.apiRoot}).done(function()
{
wp.api.loadPromise.done(function ()
{
wp.api.namespace(ies_rest.namespace).istermactive().done(function (active)
{
alert(active);
});
});
});
});
})( jQuery );
However this JS code, in WP 4.7.4/4.7.5, throws an exception in the JS console after the call to wp.api.init()
and before it reaches the call to wp.api.loadPromise()
:
Uncaught TypeError: _.includes is not a function
at wp-api.min.js?ver=4.7.4:1
at Function.h.each.h.forEach (underscore-min.js?ver=4.7.4:1)
at Object.wp.api.utils.decorateFromRoute (wp-api.min.js?ver=4.7.4:1)
at wp-api.min.js?ver=4.7.4:1
at Function.h.each.h.forEach (underscore-min.js?ver=4.7.4:1)
at n.constructFromSchema (wp-api.min.js?ver=4.7.4:1)
at n.<anonymous> (wp-api.min.js?ver=4.7.4:1)
at n.<anonymous> (backbone.min.js?ver=1.2.3:1)
at n.<anonymous> (underscore.min.js?ver=1.8.3:5)
at _ (backbone.min.js?ver=1.2.3:1)
The same code, using WP 4.8beta2, seems to work at least until it reaches the wp.api.namespace()
call, where I get:
Uncaught TypeError: wp.api.namespace is not a function
at Object.<anonymous> (https://www.virtualbit.it/wp-content/plugins/rest-api-sample//ies.js?ver=4.8-beta2:10:16)
at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
at Object.add [as done] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27748)
at Object.<anonymous> (https://www.virtualbit.it/wp-content/plugins/rest-api-sample//ies.js?ver=4.8-beta2:8:26)
at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
at Object.fireWith [as resolveWith] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:28213)
at Object.e.(anonymous function) [as resolve] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:29192)
at Object.<anonymous> (https://www.virtualbit.it/wp-includes/js/wp-api.min.js?ver=4.8-beta2:1:13404)
at i (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:27449)
at Object.fireWith [as resolveWith] (https://www.virtualbit.it/wp-includes/js/jquery/jquery.js?ver=1.12.4:2:28213)
My JS file (ies.js) is not even mentioned in the stack trace of the 4.7.x exception, while in 4.8beta2 it seems a simple syntax error, but I don't know how should I otherwise call my endpoint.
I thought it could be a WP bug (maybe a documentation bug), and I opened a bug report. It turned out it's NOT a WP bug, so this question still needs an answer, but Adam, who replied to my bug report, gave us some valuable informations.
As for the suggestion birgire gave in comments, unfortunately I have no clue about how to use the QUnit
code, maybe you can walk me through that?
If you want to try this sample plugin, you can find it here, and, just in case you are interested, you can debug the JS code at my website homepage, where this sample plugin is already installed (WP version is 4.8beta2 as of time of this writing).
&$this
is a workaround they used for PHP4 support, you should only use it if you intend to support WordPress 3.1 and below running on PHP 4.4 or older. Use$this
insteadloadPromise.done()
instead ofloadPromise.then()
?define('SCRIPT_DEBUG', false);