0

I am trying to get a JQuery autocomplete script to work in Wordpress. I believe I have everything set up correctly as I do get an error when I enter data into the input field, but then I get the following error. So, I am supposing something is wrong with the JSON, but I am just not sure how to debug that.

Uncaught SyntaxError: Unexpected token < in JSON at position 0
        at JSON.parse (<anonymous>)
        at Function.n.parseJSON (jquery.js?ver=1.12.4:4)
        at Function.a.parseJSON (jquery-migrate.min.js?ver=1.4.1:2)
        at Object._transformResult [as transformResult] (jquery.autocomplete.js?ver=4.9.8:133)
        at Object.<anonymous> (jquery.autocomplete.js?ver=4.9.8:584)
        at i (jquery.js?ver=1.12.4:2)
        at Object.fireWith [as resolveWith] (jquery.js?ver=1.12.4:2)
        at y (jquery.js?ver=1.12.4:4)
        at XMLHttpRequest.c (jquery.js?ver=1.12.4:4)

Here is the JSON that is being returned:

["Hello world!","Email Notification","Email Notification","Formidable Style","Email Notification","Email Notification","Email Notification","Chapter Maintenance - Admin View","Chapter Info - All","Featured Members"]

From other posts I have looked at the comment is that it isn't being parsed correctly, but I can't determine from my research how to resolve that.

Here is the Jquery:

jQuery(document).ready(function($) {    

    $('#autocomplete-id').autocomplete({
        source: function(name, response) {
            $.ajax({
                type: 'POST',
                dataType: 'json',
                url: '/wp-admin/admin-ajax.php',
                data: 'action=get_listing_names&name='+name,

                success: function(data) {
                    response(data);

                }
            });

        }
    });

});

Here is the function in Wordpress's functions.php I am using to return the JSON via the admin-ajax.php

add_action('wp_ajax_nopriv_get_listing_names', 'ajax_listings');
add_action('wp_ajax_get_listing_names', 'ajax_listings');


    function ajax_listings() {
        global $wpdb; //get access to the WordPress database object variable

        //get names of all businesses
        $name = $wpdb->esc_like(stripslashes($_POST['name'])).'%'; //escape for use in LIKE statement
        $sql = "select post_title 
            from $wpdb->posts 
            where post_status='publish' LIMIT 10";

        $sql = $wpdb->prepare($sql, $name);

        $results = $wpdb->get_results($sql);

        //copy the business titles to a simple array
        $titles = array();
        foreach( $results as $r )
            $titles[] = addslashes($r->post_title);



        echo json_encode($titles); //encode into JSON format and output

        die(); //stop "0" from being output
    }

I have tried to console.log(data) into the success area, but all I get back is the error without any data.

When I look at the Network tab I see the requests from when I enter a letter into the input box, but all they show are ?query=a or ?query=b.

If I click on one of those it loads up the same page I am currently on (with the autocomplete input box) with ?query=a tacked onto the end of it, so that doesn't look right.

I'm just not sure why though, if it is set up correctly to get the data from admin-ajax.php.

My main question is, what can I do to debug this further?

CRAIG
  • 977
  • 2
  • 11
  • 25
  • `'/wp-admin/admin-ajax.php'` returns HTML and not JSON – Andreas Nov 20 '18 at 17:52
  • 1
    In the Network tab, look at the Response tab to see what `/wp-admin/admin-ajax.php?action=get_listing_names&name=name` is returning. – aynber Nov 20 '18 at 17:53
  • _Not the issue, but_ pass you data like this `data: {action: get_listing_names, name: name},` – RiggsFolly Nov 20 '18 at 17:54
  • @aynber. Hmm, actually, there isn't anything from admin-ajax.php there. – CRAIG Nov 20 '18 at 17:56
  • @Andreas I am encoding the result as JSON. Are you saying you can't echo JSON from admin-ajax.php? I thought that was the only acceptable way to utilize ajax in Wordpress? Am I missing something here? – CRAIG Nov 20 '18 at 17:58
  • @RiggsFolly small issue with your suggestion. `get_listing_names` appears to be a literal string. – Taplar Nov 20 '18 at 17:59
  • @Taplar Hmm ok ignore me :) – RiggsFolly Nov 20 '18 at 18:01
  • You can return anything you want. But your setup actually returns HTML (or anything that starts with a `<`) – Andreas Nov 20 '18 at 18:02
  • Possible duplicate of ["SyntaxError: Unexpected token < in JSON at position 0" in React App](https://stackoverflow.com/questions/37280274/syntaxerror-unexpected-token-in-json-at-position-0-in-react-app) – miken32 Nov 20 '18 at 18:02
  • @RiggsFolly I'm not saying your suggestion doesn't have merit, just that that one value would need quotes around it. – Taplar Nov 20 '18 at 18:02
  • @miken32 taking a look at that. – CRAIG Nov 20 '18 at 18:04
  • I added the function I am using to produce the JSON above. – CRAIG Nov 20 '18 at 18:05
  • It's basically just saying that you're outputting HTML instead of JSON, there's something wrong on the server side. – miken32 Nov 20 '18 at 18:05
  • @miken32 Roger that. Yeah, I see it. I see them mentioning console.warn, console.error, but not sure how to utilize that. Do I put it directly into the console? Do I put it into the script? Do I add the data to it? Any tips on how I can figure out how to resolve this? – CRAIG Nov 20 '18 at 18:08
  • The output from your server is not JSON, simply pulling up the relevant URL in a web browser or looking at the response in your web inspector should show you the output. – miken32 Nov 20 '18 at 18:12
  • Try changing your dataType from JSON to text while testing it. You should be able to then use console.log() to see what you're receiving. – aynber Nov 20 '18 at 18:13
  • @miken32 Ok, so I went to the exact URL and I viewed source and got this: ["Hello world!","Email Notification","Email Notification","Formidable Style","Email Notification","Email Notification","Email Notification","Chapter Maintenance - Admin View","Chapter Info - All","Featured Members"] – CRAIG Nov 20 '18 at 18:20
  • Is that the URL that the jQuery script is requesting though? – miken32 Nov 20 '18 at 18:21
  • Yeah it appears to be. This is exactly the URL I put into the browser: mydomain.com/wp-admin/admin-ajax.php?action=get_listing_names&name=a You can see in the script above it's the same (unless I am missing something) – CRAIG Nov 20 '18 at 18:23
  • BUT, again, when I look at the Network tab, everytime I enter a letter into my input box, that URL doesn't appear. What appears is only ?query=a . That doesn't seem right. Shouldn't the wp-admin/admin-ajax.php url appear there? – CRAIG Nov 20 '18 at 18:25

1 Answers1

2

Here is my code, Maybe this will help you.

JS file(global.js) Code

jQuery(document).ready(function($) {    

var searchRequest;
$('#autocomplete-id').autoComplete({
    minChars: 2,
    source: function(name, result){
        try { searchRequest.abort(); } catch(e){}
        searchRequest = $.post(global.ajax, { name: name, action: 'get_listing_names' }, function(res) {
            result(res.data);
        });
    }
});

});

Functions.php File code

    <?php
/**
 * Enqueue scripts and styles.
 *
 * @since 1.0.0
 */
function ja_global_enqueues() {
    wp_enqueue_style(
        'jquery-auto-complete',
        'https://cdnjs.cloudflare.com/ajax/libs/jquery-autocomplete/1.0.7/jquery.auto-complete.css',
        array(),
        '1.0.7'
    );
    wp_enqueue_script(
        'jquery-auto-complete',
        'https://cdnjs.cloudflare.com/ajax/libs/jquery-autocomplete/1.0.7/jquery.auto-complete.min.js',
        array( 'jquery' ),
        '1.0.7',
        true
    );
    wp_enqueue_script(
        'global',
        get_template_directory_uri() . '/js/global.js',
        array( 'jquery' ),
        '1.0.0',
        true
    );
    wp_localize_script(
        'global',
        'global',
        array(
            'ajax' => admin_url( 'admin-ajax.php' ),
        )
    );
}
add_action( 'wp_enqueue_scripts', 'ja_global_enqueues' );


add_action('wp_ajax_nopriv_get_listing_names', 'ajax_listings');
add_action('wp_ajax_get_listing_names', 'ajax_listings');


function ajax_listings() {
    global $wpdb; //get access to the WordPress database object variable

    //get names of all businesses
    $name = $wpdb->esc_like(stripslashes($_POST['name'])).'%'; //escape for use in LIKE statement
    $sql = "select post_title 
        from $wpdb->posts 
        where post_status='publish' LIMIT 10";

    $sql = $wpdb->prepare($sql, $name);

    $results = $wpdb->get_results($sql);

    //copy the business titles to a simple array
    $titles = array();

    foreach( $results as $r ){
        $titles[] = addslashes($r->post_title);
    }

    wp_send_json_success( $titles );        

}
  • Hey @Jaydeep. Thanks for answering! What is the Global.js file? I don't have this file. (At least I don't think I do?) – CRAIG Nov 23 '18 at 04:53
  • Hello @CRAIG, You have to use your jQuery Code in some JS file and have to put localize your js go use the AJAX in Wordpress. – Jaydeep Jagani Nov 23 '18 at 11:53
  • Woo hoo! Thanks so much @Jaydeep! So, the critical missing step for me was putting the jquery in that separate file. Once i did that I was able to get the rest sorted out. Thanks so much for the help. – CRAIG Nov 24 '18 at 04:08
  • One final question. How could I return separate data for the input field and a separate value (is number) for the value field? – CRAIG Nov 24 '18 at 17:49
  • Can you Please elaborate more.. !! – Jaydeep Jagani Nov 26 '18 at 04:12