3

I have a Advanced Custom Field on WordPress edit post admin page that requires some validation. This validation is done via ajax (I am pretty sure though that acf and WordPress are irrelevant to this question).

Unfortunately I get the following error in the console: Uncaught Not a valid flickr.com url (line 16) for the following code:

jQuery(document).ready(function($) {
    var initialVal = $('#acf-field_560aabcf8dbef').val();
    $('#acf-field_560aabcf8dbef').on('paste', function(e) {
        var pasteData = e.originalEvent.clipboardData.getData('text');
        if (initialVal !== pasteData) {
            try {
                $.get(ajaxurl, 
                    {
                        'action': 'ai_check_url_id',
                        'idOrUrl': pasteData
                    },
                    function(response) {
                        response = $.parseJSON(response);
                        if (response.error) {
                            throw response.error.msg;
                        }

                        console.log(response);
                    }
                );
            } catch (e) {
                console.error(e);
            }
        };
    });
});

The php function

<?php
    function ajaxIdOrUrl() 
    {
        try {
            echo $this->idOrUrl($_GET['idOrUrl']);
        } catch (\Exception $e) {
            echo json_encode([
                'error' => [
                    'msg' => $e->getMessage(),
                    'code' => $e->getCode(),
                ],
            ]);
        }

        wp_die();
    }

What it does is:

  • the ajaxurl is defined on the page
  • on a paste event check if the value has changed
  • if it has, make a get request and send the changed data along
  • the answer is either an ID or an error array

Can anybody point me in the right direction why this shows up as being uncaught (the code works fine when there is no error)?

alpipego
  • 3,223
  • 2
  • 17
  • 28
  • 1
    My guess would be that it's because your code in the closure (which you're passing as a parameter to `jQuery.get()` to execute asynchronously) is being executed outside of the scope of your try block, by code other than yours. I'd imagine you want to pass an error handling closure to `get()` rather than try to wrap everything yourself. You're probably long through the try block and onto later code by the time the Ajax response comes back from the server. I'm no JS expert, though, so I'll leave it to someone more qualified to answer properly. – Matt Gibson Sep 30 '15 at 07:50
  • I would suggest you to use `error` callback to handle **server errors** and use `try-catch` inside your success callback to handle `json parsing` or any other JavaScript run-time errors.. – Rayon Sep 30 '15 at 08:08
  • @RayonDabre the `$.get` method does not have an `error` callback (afaik none of the ajax shorthands have). I know that there are workarounds/other ways of achieving this. – alpipego Sep 30 '15 at 08:36
  • @alpipego, How about `$.get( "example.php", function() { alert( "success" ); }) .done(function() { alert( "second success" ); }) .fail(function() { alert( "error" ); })` ? – Rayon Sep 30 '15 at 09:33
  • The response as such does not trigger a jQuery `.fail()`. The response would have to be something like `header('HTTP/1.1 400 Bad Request');`. The way the php response is designed it'll always defer to a `.done()`. For the moment I have implemented something similar to this answer http://stackoverflow.com/a/21113451/2105015 – alpipego Sep 30 '15 at 09:40
  • 1
    @MattGibson you are completely right. I somehow forgot what the first A in AJAX stands for... – alpipego Sep 30 '15 at 10:29

1 Answers1

1

Thanks to the input of Matt Gibson and this answer. I have reworked my jQuery to this:

jQuery(document).ready(function($) {
    var initialVal = $('#acf-field_560aabcf8dbef').val();
    $('#acf-field_560aabcf8dbef').on('paste', function(e) {
        var pasteData = e.originalEvent.clipboardData.getData('text');
        if (initialVal !== pasteData) {
            $.get(
                ajaxurl, 
                {
                    'action': 'ai_check_url_id',
                    'idOrUrl': idOrUrl
                }
            )
            .then(function(response) {
                response = $.parseJSON(response);
                if (response.error) {
                    return $.Deferred().reject(response.error)
                } else {
                    return response;
                }
            })
            .done(function(response) {
                console.log(response);
                // more sucess handling
            })
            .fail(function(err) {
                console.error(err.msg);
                // more error handling
            });
        };
    });
});
Community
  • 1
  • 1
alpipego
  • 3,223
  • 2
  • 17
  • 28