最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

ajax - Wordpress Heartbeat API cannot parse data

programmeradmin3浏览0评论

I want to use WP-API heartbeat to open a connection to two displays and have them reflect what the other is saying with each send and tick.

It used to work when the heartbeat API came out in 3.6 - but now at the latest version it is outputting an error:

SyntaxError: JSON Parse error: Unexpected identifier "SyntaxError"

I have tried following other answers on the web to parse the json error or find where it is failing but nothing seems to come out out of it other than it is returning the same url than the response from the server.

function mb_heartbeat() {
    wp_enqueue_script( 'heartbeat' );
    add_action( 'wp_footer', 'mb_heartbeat_footer' );
}

//our js to send/process
function mb_heartbeat_footer() { ?>
<script>
$(document).ready( function() {

    // send the user id
    $(document).on( "heartbeat-send.mb-location-change", function( event, data ) {
        data.mb_user_id = $('input[name="mb_user_id"]').val();
    });

    // receive the location
    $(document).on( "heartbeat-tick.mb-location-change", function( event, data ) {
        data.mb_user_location && $("input#mb_user_location" + data.location ).prop( "checked","checked" );
    });

    // log errors
    $(document).on( "heartbeat-error.mb-location-change", function( event, jqXHR, textStatus, error ) {
        console.log( textStatus + ' ----------- ' + error );
    })
});
</script>
<?php }

// server-side code
function mb_heartbeat_received( $response, $data, $screen_id ) {

    $mb_userid = ( empty($data['mb_user_id']) || !is_numeric($data['mb_user_id']) ? null : $data['mb_user_id'] );

    $mb_userid = absint( $mb_userid );

    if( !$mb_userid ) {
        return $response;
    }

    $response['mb_user_location'] = get_user_meta( $mb_userid, 'mb_user_location_current', true );

    return $response;
}

// do it
add_action( 'init',                 'mb_heartbeat'                  );
add_filter( 'heartbeat_received',   'mb_heartbeat_received', 10, 2  );
add_filter( 'heartbeat_settings',   'mb_heartbeat_settings'         );

I want to use WP-API heartbeat to open a connection to two displays and have them reflect what the other is saying with each send and tick.

It used to work when the heartbeat API came out in 3.6 - but now at the latest version it is outputting an error:

SyntaxError: JSON Parse error: Unexpected identifier "SyntaxError"

I have tried following other answers on the web to parse the json error or find where it is failing but nothing seems to come out out of it other than it is returning the same url than the response from the server.

function mb_heartbeat() {
    wp_enqueue_script( 'heartbeat' );
    add_action( 'wp_footer', 'mb_heartbeat_footer' );
}

//our js to send/process
function mb_heartbeat_footer() { ?>
<script>
$(document).ready( function() {

    // send the user id
    $(document).on( "heartbeat-send.mb-location-change", function( event, data ) {
        data.mb_user_id = $('input[name="mb_user_id"]').val();
    });

    // receive the location
    $(document).on( "heartbeat-tick.mb-location-change", function( event, data ) {
        data.mb_user_location && $("input#mb_user_location" + data.location ).prop( "checked","checked" );
    });

    // log errors
    $(document).on( "heartbeat-error.mb-location-change", function( event, jqXHR, textStatus, error ) {
        console.log( textStatus + ' ----------- ' + error );
    })
});
</script>
<?php }

// server-side code
function mb_heartbeat_received( $response, $data, $screen_id ) {

    $mb_userid = ( empty($data['mb_user_id']) || !is_numeric($data['mb_user_id']) ? null : $data['mb_user_id'] );

    $mb_userid = absint( $mb_userid );

    if( !$mb_userid ) {
        return $response;
    }

    $response['mb_user_location'] = get_user_meta( $mb_userid, 'mb_user_location_current', true );

    return $response;
}

// do it
add_action( 'init',                 'mb_heartbeat'                  );
add_filter( 'heartbeat_received',   'mb_heartbeat_received', 10, 2  );
add_filter( 'heartbeat_settings',   'mb_heartbeat_settings'         );
Share Improve this question edited Nov 14, 2019 at 4:22 markb asked Sep 26, 2019 at 6:08 markbmarkb 2996 silver badges18 bronze badges 7
  • 2 Please enhance the error message, like from the console inside the browser. Is the error from the JSON or inside the script. Also, do you write javascript code for the jQuery library, have you enqueue before running your script, it is not visible in your question? – bueltge Commented Nov 13, 2019 at 14:45
  • @bueltge That is the error message from the console. When I go through the XHR in Chrome dev tools, it seems to be returning the webpage not the return from the server. Yes I have enqueued the heartbeat via the API Documentation. – markb Commented Nov 14, 2019 at 4:10
  • However, often get the console also the file and line of the problem that's the result in this error message. – bueltge Commented Nov 14, 2019 at 6:40
  • And try, if you have the right enqueue of jQuery - jQuery(document).ready( function($) { – bueltge Commented Nov 14, 2019 at 6:40
  • 1 Can you show your full Heartbeat-related code, specifically the PHP part which hooks to heartbeat_send? Have you tried deactivating plugins to see if a plugin is causing the issue? – Sally CJ Commented Nov 16, 2019 at 14:46
 |  Show 2 more comments

2 Answers 2

Reset to default 2 +50

Not 100% sure if that's the cause but can you try replacing $ with jQuery?

I remember seeing something like this in the past in a similar case.

The message which is likely hidden somewhere would be "$ is not function" because jQuery not properly bound to the client.

You can either use jQuery instead of $ like suggested before, or you move your heartbeat callbacks out of your php into a js file and use proper binding for example:

(function ($) {
      ... your code here
})(jQuery);

I'd also suggest to not use wp_footer to get your scripts to the client unless there's a good reason for it. By using wp_enqueue_scripts hook you can ensure that your scripts end up in the right place. This also gives you the ability to control the load order of your scripts through dependencies.

I noticed that you use wp_enqueue_script in the WP init hook, this may lead to unexpected results, to make sure everything works as intended I suggest to change to either wp_enqueue_scripts or admin_enqueue_scripts depending on your needs. You can read more about these hooks here:

https://developer.wordpress/reference/functions/wp_enqueue_scripts/ https://developer.wordpress/reference/hooks/admin_enqueue_scripts/

hope this helps.

Best, Sebo

发布评论

评论列表(0)

  1. 暂无评论