Ajax jquery success scope
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.
Related videos on Youtube
Chris
Updated on July 09, 2022Comments
-
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 over 14 yearsWhoa whoa whoa whoa whoa.
new
is a reserved word: developer.mozilla.org/en/Core_JavaScript_1.5_Reference/… -
Chris over 14 yearsDon'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 over 14 yearsHmm, 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 over 14 years@Chris: re:
new
, I figured as much. :) -
Crescent Fresh over 14 years@Chris: re the closure not working, make sure
doop
is itself referring to the expectedthis
. If you just calldoop()
for example,this
will just point to thewindow
object. -
Chris over 14 yearsOk, 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 over 14 yearsThanks +1. This is the same as crescentfresh's answer and it solves "part of the problem".. will update the question with more troubleshooting.
-
Chris over 14 yearsNow 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 almost 12 yearsYou really should not use reserved words like
new
as variable names. -
Tim Holt over 11 yearsAgreeing 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 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 almost 11 yearsYou'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, usingcontext: this
does it once and has much more flexible use cases.