0

I have been trying for a few days now to convert my tracking pixel JS functionality to use a 204 "no_content" response.

I can easily get this working, but I need to be able to fire a callback function afterwards.

The following doesn't seem to ever get fired once the 204 is returned.

    beacon: function (opts) {
        var beacon = new Image();

        opts = $.extend(true, {}, {
            url: pum_vars.ajaxurl || null,
            data: {
                action: 'pum_analytics',
                _cache: (+(new Date()))
            },
            error: function () {
                console.log('error');
            },
            success: function () {
                console.log('success');
            }
        }, opts);

        // Create a beacon if a url is provided
        if (opts.url) {
            // Attach the event handlers to the image object
            if (beacon.onerror) {
                beacon.onerror = opts.error;
            }

            if (beacon.onload) {
                beacon.onload = opts.success;
            }

            $(beacon).on('load', function( response, status, xhr ){
                alert(status);
            });

            // Attach the src for the script call
            beacon.src = opts.url + '?' + $.param(opts.data);
        }
    }

The tracking is logged properly, but no alert or console log messages. Is this possible or am I just wasting my time?

Edit ------

Based on the solution below here is the final version (this assumes that both an error & success will use the same callback.

    beacon: function (opts) {
        var beacon = new Image();

        opts = $.extend(true, {}, {
            url: pum_vars.ajaxurl || null,
            data: {
                action: 'pum_analytics',
                _cache: (+(new Date()))
            },
            callback: function () {
                console.log('tracked');
            }
        }, opts);

        // Create a beacon if a url is provided
        if (opts.url) {
            // Attach the event handlers to the image object
            $(beacon).on('error success done', opts.callback);

            // Attach the src for the script call
            beacon.src = opts.url + '?' + $.param(opts.data);
        }
    }
Daniel Iser
  • 441
  • 4
  • 9

1 Answers1

1

You aren't attaching any callbacks to image. Your test if (beacon.onerror) results in false because beacon.onerror is null.

You should use if( "onerror" in beacon ) to tests whether beacon has onerror property.

But why dont you just use jquery's method on?

$(beacon).on("error", function() {
    alert("Jquery error");
});

$(beacon).on("done", function() {
    alert("Jquery done");
});
Buksy
  • 11,571
  • 9
  • 62
  • 69
  • Wow, could have sworn I tried .on('error') previously. Works perfectly fine now. Doh!. – Daniel Iser Aug 12 '16 at 07:22
  • Would changing it to if (!beacon.onerror) work similarly to if( "onerror" in beacon )? – Daniel Iser Aug 12 '16 at 07:23
  • To confirm that for anyone else, !beacon.onerror works just fine as well. Thanks @Busky for a quick solution. – Daniel Iser Aug 12 '16 at 07:26
  • 1
    `!beacon.onerror` isn't same as `"onerror" in beacon` ... The first tests whether negated value of property equals to true, second tests whether property is present. Because `!null = true` and `!undefined = true` your condition will return true even if property doesn't exist in object. – Buksy Aug 12 '16 at 08:52