Ajax jquery success scope

31,578

Solution 1

First of all new is a reserved word. You need to rename that variable.

To answer your question, Yes, you need to save this in a variable outside the success callback, and reference it inside your success handler code:

var that = this;
$.ajax({
    // ...
    success: function(resp) {
        if(resp == 1) {
            $(that).siblings('.old').html($new);
        }
    }
})

This is called a closure.

Solution 2

You should use the context setting as in http://api.jquery.com/jQuery.ajax/

function doop(){
    var old = $(this).siblings('.old').html();
    var newValue = $(this).siblings('.new').val();

    $.ajax({
        url: 'doop.php',
        type: 'POST',
        context: this,
        data: 'before=' + old + '&after=' + newValue,
        success: function(resp) {
            if(resp == 1) {
                $(this).siblings('.old').html(newValue);
            }
        }
    });

    return false;
}

"this" will be transfer to the success scope and will act as expected.

Solution 3

this is bound to the object to which the executing function was applied. That could be some AJAX response object, or the global object (window), or something else (depending on the implementation of $.ajax.

Do I need to capture $(this) into a variable before entering the $.ajax call, and then pass it as a parameter to the $.ajax call? or do I need to pass it to the anonymous success function? If that's going to solve the problem, where do I pass it to the $.ajax?

You do indeed need a way to capture the value of this before defining the success function. Creating a closure is the way to do this. You need to define a separate variable (e.g. self):

function doop() {
    var old = $(this).siblings('.old').html();
    var new = $(this).siblings('.new').val();

    var self = this;

    $.ajax({
        url: 'doop.php',
        type: 'POST',
        data: 'before=' + old + '&after=' + new,
        success: function(resp) {
            if(resp == 1) {
                $(self).siblings('.old').html(new);
            }
        }
    });

    return false;
}

The success function will retain the value of self when invoked, and should behave as you expected.

Share:
31,578

Related videos on Youtube

Chris
Author by

Chris

Updated on July 09, 2022

Comments

  • Chris
    Chris almost 2 years

    I have this ajax call to a doop.php.

        function doop(){
            var old = $(this).siblings('.old').html();
            var new = $(this).siblings('.new').val();
    
            $.ajax({
                url: 'doop.php',
                type: 'POST',
                data: 'before=' + old + '&after=' + new,
                success: function(resp) {
                    if(resp == 1) {
                        $(this).siblings('.old').html(new);
                    }
                }
            });
    
            return false;
        }
    

    My problem is that the $(this).siblings('.old').html(new); line isn't doing what it's supposed to do.

    thanks.. all helpful comments/answers are voted up.

    Update: it appears that half of the problem was the scope (thanks for the answers that helped me clarify that), but the other half is that I'm trying to use ajax in a synchronous manner. I've created a new post

    • Crescent Fresh
      Crescent Fresh over 14 years
      Whoa whoa whoa whoa whoa. new is a reserved word: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/…
    • Chris
      Chris over 14 years
      Don't worry about new, it's called something else in my code. Just called it new to make the code more understandable for you guys
  • Chris
    Chris over 14 years
    Hmm, weird, I tried something very similar to what you've done, but I did var saveit = $(this); didn't work. I'll try this one now.. Also don't worry about new, it's called something else in my code.
  • Crescent Fresh
    Crescent Fresh over 14 years
    @Chris: re: new, I figured as much. :)
  • Crescent Fresh
    Crescent Fresh over 14 years
    @Chris: re the closure not working, make sure doop is itself referring to the expected this. If you just call doop() for example, this will just point to the window object.
  • Chris
    Chris over 14 years
    Ok, after the closure, I'm able to target the right this/that (I tested it with show/hide and i know it's targeting the right thing). However, it's not updating the html.. I'm doing some troubleshooting and will update my answer above, please check back when you get a chance, thanks.
  • Chris
    Chris over 14 years
    Thanks +1. This is the same as crescentfresh's answer and it solves "part of the problem".. will update the question with more troubleshooting.
  • Chris
    Chris over 14 years
    Now that I've done my troubleshooting, I've come to the conclusion that the second half of the problem is that I should be using synchronous ajax. not asynchronous. Updaing my question above and posting a new question.
  • Tomalak
    Tomalak almost 12 years
    You really should not use reserved words like new as variable names.
  • Tim Holt
    Tim Holt over 11 years
    Agreeing with Nick - this is the correct approach. Consider that the "save it in another variable" approach won't work if you have function "doop" called when one of multiple buttons are clicked or some other such duplication.
  • oucil
    oucil almost 11 years
    +1 Much more flexible answer than the selected one, in our case, the var would have to be unique for every single item in a very long list of items adding code bloat, this is a few short characters and gives much more flexible use cases.
  • oucil
    oucil almost 11 years
    You're correct on the new keyword, but this adds far too much code bloat in a long list where it's added dynamically, each var would have to be unique, where as in the answer below, using context: this does it once and has much more flexible use cases.