SitePoint Sponsor

User Tag List

Results 1 to 7 of 7
  1. #1
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    188
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Odd variable value capture timing

    I have the following jQuery code that our back end guy came up with and he has asked me for help on it. The issue is that the value for the closeMsg variable is supposed to be set on either the success or the failure of the Ajax post but it bizarrely is not set unless a subsequent alert is set to display it. Then that alert doesn't display but everything after that first alert does. Here is the code and I'm adding in comments around the alert to explain it a little better.

    Code:
    $('#confirmDeleteDelete').click(function (e) {
        var deleteUrl = baseUrl + 'delete/' + $('#confirmDeleteDelete').attr('name');
        var closeMsg = null;
        var closeUrl = null;
    
        //alert(deleteUrl);
        $.ajax({
            url: deleteUrl,
            type: 'POST',
            //data: {},
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                closeMsg = 'Successfully deleted record';
                closeUrl = baseUrl;
            },
            error: function (xhr, status, error) {
                closeMsg = 'Could not delete record, please try again';
                closeUrl = null;
            }
        });
    
        $('#promptDeleteMsg').hide();
        $('#confirmDeleteDelete').hide();
        $('#confirmDeleteCancel').hide();
    
        alert(closeMsg); // Here's the first alert; when it displays it shows a value of "null"
        alert(closeMsg); // Here's the second alert; when it displays it shows a value of "Successfully deleted record" (assuming a successful Ajax post)
        $('#promptDeleteMsg').after('<p id="#confirmDeleteMsg" />').text(closeMsg).show(); // This is where we actually want the value to show up but it doesn't unless at least the first alert is in place
        $('#confirmDeleteClose').attr('name', closeUrl);
    
        $('#confirmDeleteClose').show();
        e.preventDefault();
    });
    Any ideas? If it helps anything there doesn't seem to be any problem capturing the associated closeUrl variable value.

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    This would be completely expected behaviour. The code above is pretty sound and it doesn't actually need too much more to make it work

    The reason it fails is because the code is asynchronously connecting to the server and retrieving data, this also means that it is not blocking the other code from running. So what happens in a normal scenario is this:


    • User clicks button
    • Button event handler kicks in
    • AJAX request fires
    • Code after the AJAX request call runs
    • AJAX request finishes, success and error callbacks are called if necessary


    However, in your scenario the alert() calls block the code from continuing, but the AJAX request finishes, the second alert now has a value for closeMsg.

    To fix this code, we can simply add another callback in to your AJAX call for "complete" ... as per the jQuery.ajax() documentation, 'complete' fires after success and/or error have been called.

    Code javascript:
    $('#confirmDeleteDelete').click(function (e) {
     
        //declare all variables at the top, this can be done with one 'var' statement :)
        var deleteUrl = baseUrl + 'delete/' + $('#confirmDeleteDelete').attr('name'),
            closeMsg = null,
            closeUrl = null;
     
        //prevent default event handler from occurring as early as possible
        e.preventDefault();
     
        //we can combine all these in to a single selector
        $('#promptDeleteMsg, #confirmDeleteDelete, #confirmDeleteCancel').hide();
     
        $.ajax({
            url: deleteUrl,
            type: 'POST',
            //data: {},
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                closeMsg = 'Successfully deleted record';
                closeUrl = baseUrl;
            },
            error: function (xhr, status, error) {
                closeMsg = 'Could not delete record, please try again';
                closeUrl = null;
            },
            //the complete callback will fire after the success / error callbacks
            complete: function(xhr, status) {
                $('#promptDeleteMsg').after('<p id="#confirmDeleteMsg" />').text(closeMsg).show();
                $('#confirmDeleteClose').attr('name', closeUrl).show(); //it's fine to chain .show() on here as well.
            }
        });
     
    });
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    188
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks, AussieJohn. Going to implement now.

  4. #4
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    188
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Okay, that one worked. Now I'm trying to get a similar one to work.

    Code JavaScript:
    if (isTagDefined(ajaxgetleftnav)) {
        if (isTagDefined(getdataids))
            ajaxgetleftnav = ajaxgetleftnav + getdataids;
     
        $.ajax({
            url: ajaxgetleftnav,
            type: 'GET',
            //data: {},
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                if (isTagDefined(leftnav_datadiv)) {
                    $(leftnav_datadiv).html(data);
                    $(leftnav_datadiv).dataTable();
                }
                //$('.leftnav_status').html('success getting data');
                //$('.leftnav_status').removeClass('content_error').addClass('content_success');
                if (isTagDefined(leftnav_navdiv) && isTagDefined(leftnavCTApath)) {
                    $(leftnav_navdiv).load(leftnavCTApath);
                    alert('hi planet'); // need to find a way for the next line to work without this alert being in place;
                    $('#createitem IMG').after('&nbsp;New&nbsp;' + entityName);
                }
            },
            error: function (xhr, status, error) {
                console.log('fail');
                $('.leftnav_status').html('error getting data');
                $('.leftnav_status').removeClass('content_success').addClass('content_error');
            }
        });
    }

    I suppose it's a matter of where to put the e.preventDefault statement and maybe where to put a complete statement too, but this example is different because I want to do something within a success statement rather than after the success/error part, but none of my tinkering has been successful yet.

  5. #5
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Code javascript:
    if (isTagDefined(leftnav_navdiv) && isTagDefined(leftnavCTApath)) {
        $(leftnav_navdiv).load(leftnavCTApath);
        alert('hi planet'); // need to find a way for the next line to work without this alert being in place;
        $('#createitem IMG').after('&nbsp;New&nbsp;' + entityName);
    }

    I'm not sure where that would be falling over, is entityName already defined (and does "#createitem img" already exist?).
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  6. #6
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    188
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes to "#createitem img" already existing (yeah, I'm weird, I put HTML elements within JavaScript statements in uppercase to increase readability for myself). Let me check on the entityName issue...

  7. #7
    SitePoint Zealot
    Join Date
    Jul 2008
    Posts
    188
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    UPDATE: It's looking like it could be an issue of when entityName is defined. I'm not getting a clear answer on that right now and might have to wait until our back end guy comes back from his days off.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •