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'         );
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
    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
    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
    Nov 14, 2019 at 6:40
  • And try, if you have the right enqueue of jQuery - jQuery(document).ready( function($) {
    – bueltge
    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
    Nov 16, 2019 at 14:46

2 Answers 2

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.

2
  • You should ALWAYS use "jQuery" instead of "$" in WordPress. So many problems.
    – John Dee
    Nov 19, 2019 at 20:33
  • well that seemed to solve one part of it.
    – markb
    Nov 21, 2019 at 7:08
0

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.org/reference/functions/wp_enqueue_scripts/ https://developer.wordpress.org/reference/hooks/admin_enqueue_scripts/

hope this helps.

Best, Sebo

Your Answer

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

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