How to pass this object of jquery into inner success function? - javascript

below is my code. I want to change the each mainimage src based on ajax call back.
jQuery('.xxx img[src*="mainimage"]').each(function() {
vobj = $(this);
var inmainurl = 'https://xxx.kki/api/oembed.json?url=' + $(this).attr('src');
$.ajax({
url: inmainurl,
dataType: 'json',
success: function(result) {
$(this).attr('src', result.thumbnail_url); //this is not working.
}
});
});
below is not working
success: function (result) {
$(this).attr('src',result.thumbnail_url);//this is not working.
}
how to achieve that?

If you change your inner $(this).attr to vobj.attr does that solve your problem?
See that vobj is your defined variable.

Instead of
$(this).attr('src', result.thumbnail_url);
write
vobj.attr('src', result.thumbnail_url);
this is the function context and it is different for both functions, but the ajax callback has access to the vobj variable.

You need to use a closure in the loop, otherwise the vobj variable will have changed to the next element after the $.ajax call is made. You also need to use the vobj variable inside the success handler. Try this:
jQuery('.xxx img[src*="mainimage"]').each(function() {
(function($el) {
$.ajax({
url: 'https://xxx.kki/api/oembed.json?url=' + $el.attr('src');,
dataType: 'json',
success: function(result) {
$el.attr('src', result.thumbnail_url);
}
});
})($(this));
});

Related

Using this.setAttribute in an Ajax call [duplicate]

It seems that i cannot access $(this) inside jquery ajax success function. please see below code.
$.ajax({
type: 'post',
url: '<?php echo site_url('user/accept_deny_friendship_request')?>',
data: 'action='+$action+'&user_id='+$user_id,
success: function(response){
//cannot access $(this) here $(this).parent().remove();
}
});
What should $(this) be? If you have a reference to it outside that function, you can just store it into a variable.
$('#someLink').click(function() {
var $t = $(this);
$.ajax( ... , function() {
$t.parent().remove();
});
}
Check out the context option - works perfectly for me:
$.ajax({
context: this,
type: 'post',
url: '<?php echo site_url('user/accept_deny_friendship_request')?>',
data: 'action='+$action+'&user_id='+$user_id,
success: function(response){
//can access this now!
}
});
If you want this to be this in the context of your ajax call, you can also use .bind() like the following:
$.ajax({
url: 'some_url'
success: function(data) {
// do something 'this'
}.bind(this)
})
It binds the value of this inside the success callback to this outside.
Try calling $.proxy, to change the scope of this inside the function:
$.ajax({
success: $.proxy(function(response) { $(this).parent().bla(); }, $(this));
});
I can't see $(this) referencing anything but easier way would be to give the element a class or id and reference that from jquery:
Instead of:
$(this).parent().remove();
You could do:
$('#element_id').parent().remove();
Note: Here I assume that you are dealing with one element/iteration.
Now, you can simply achieve it using ES6 arrow function. You can convert the anonymous function to arrow function expression as below:
$.ajax({
..,
success: (response) => {
// access this outside of this function scope by using `this`
}
});
Make sure to use transpiler such as babel to provide support for older browsers.

Delay subsequent ajax call until first ajax call is complete

I am having some trouble with the timing of javascript events. The problem I am having is that one part of the code seems to be executing before another part of the code completes. I need to ensure that the first code finishes before the latter code begins. Here is the initial code:
function(){
myLoop(); //this needs to complete before the call to myMethod below
$.ajax({
url: sURL + "myController/myMethod",
success: function() {
$.msg("My Success Message",{live:10000});
error: function(){
$.msg("My Error Message",{live:10000});
});
}
And here is the code that loops and inserts records into a db:
function myLoop(){
$('input[name=c_maybe].c_box').each(function(){
if( $(this).prop('checked') ){
var rn = $(this).prop('value');
$.ajax({
url: sURL + 'myController/myInsert',
type:"POST",
dataType: 'text',
data: {'rn': rn},
success: function(data) {
//not sure what to do on success.
}
});
}
});
}
The problem that seems to be happening is that the call to myController\myMethod is happening before myLoop completes inserting all the records into the database.
Can someone suggest a way for me to redesign this code so that I can ensure that myController\myMethod is not called until myLoop has completely finished?
Thanks.
function myLoop() {
var jqxhrs = [];
if( $(this).prop('checked') ){
var rn = $(this).prop('value');
jqxhrs.push($.ajax({...
}
return jqxhrs;
}
function () {
$.when.apply(undefined, myLoop()).done(function () {
$.ajax({
url: sURL + "myController/myMethod",
...
});
}
$.when.apply is used to call $.when on the array of ajax requests, so .done is not called until they are all complete.
You can use the $.when function that has been added to jQuery.
It goes something like this:
$.when(ajaxFunction1(), ajaxFunction1()).done(function(response1, response2){
// when the function calls are done this code here will be executed -> the response will be passed as parameters corresponding to the functions -> response1, response2
});
Or you can try to use "beforeSend" within the ajax function:
$.ajax({
beforeSend: function(){
alert("doing stuff before the ajax call ...");
},
success: function(){
alert("Whoa!");
}
});
You can make the ajax call synchronous. That way, the execution will be blocked till ajax call returns:
$.ajax({
url: sURL + 'myController/myInsert',
type:"POST",
dataType: 'text',
data: {'rn': rn},
async: false,
success: function(data) {
//not sure what to do on success.
}
});

Page with Ajax function does not refresh data

My scripts are working perfectly fine. However, the content does not refresh itself to get new data. Why is it so?
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
}
});
setTimeout('updateMsg()', 4000);
}
updateMsg();
Your setTimeout can reference updateMsg directly instead of using a string:
var timeout;
function updateMsg() {
$.ajax({
url: "/recent/notifications/",
cache: false,
success: function(html){
$("#profile_notifarea_msgbox").html(html);
timeout = setTimeout(updateMsg, 4000);
}
});
}
updateMsg();
function stopUpdate() {
clearTimeout(timeout);
}
To stop the continuous update you save a reference to the setTimeout in a variable and then call clearTimeout and pass in that variable. In this example, you would just call the function stopUpdate() to cancel the updates.
when you use ajax with jQuery try to always put an error function, in this way you can identify if something is wrong with the request

$(this) selector issue jquery

i have this simple jquery function here.Clicking over a button i want to alert its own class before ajax and again upon succession..but the selector "$(this)" in the last situation is not working and the alert returns "undefined"..
why?
$(".button").live("click",function(){
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(this).attr('class')); //returns undefined
}
});
I would do it like this, store $(this) in a variable so you can use it throughout the function without having to perform a jQuery lookup every time, and you also will not have to depend on the scope to provide the correct element for $(this)
$(".button").live("click",function(){
var button = $(this);
alert(button.attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(button.attr('class')); //should also return "button"
}
});
});
wrapping this only once also is a performance enhancement
This will make it work:
$(".button").live("click", function() {
var button = this;
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) {
alert($(button).attr('class'));
}
});
});
You cannot use the this reference inside nested functions. The success function is a nested function and it has its own this value. If you need the reference to the button inside that nested function, you have to declare a local variable (like button).
function clickHandler() {
// this == element that was clicked
function ajaxHandler() {
// this != element that was clicked
}
}
Try adding var self = $(this); when you declare the function, and then use self instead of $(this)
So your code looks like this:
$(".button").live("click",function(){
var self = $(this);
alert($(this).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert(self.attr('class')); //returns undefined
}
});
Lots of people have posted the solution for this so I won't post the code. Just wanted to mention the reason is because since the success method is a callback your context of $(this) isn't valid anymore. So you need to assign it to a variable and store it for your own use.
$(this) only exists when referencing an HTML object in the DOM. Since you've tried using in the success function of the AJAX call, $(this) has no reference. So for example, in the following code $(this) refers to the item to returned by the jQuery selector:
$('.button').each(function() {
alert($(this));
});
You will need to use a selector to return the item in global scope, and then pass this to the success function in the AJAX call:
var myButton = $('.button');
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html) { alert(myButton.attr('class')); /* returns button */ }
});
Take a look at the context section here. Basically, what seems to be happening in your code is that the reference to this no longer applies. Makes sense, given that the context of the code has moved on while the AJAX callback is being handled asynchronously. Explicitly setting the context to a particular object in the .ajax() call will carry a reference to the context into the callback function.
You can either add a context: this property to the hash that is passed to the $.ajax call, that way the success handle will it's context set properly, or you can also do something like:
success: $.proxy(function(html) { // using $.proxy will bind the function scope to this
alert($(this).attr('class'));
}, this);
or, another technique I've seen:
$(".button").live("click",function(){
var self = this;
alert($(self).attr('class')); //returns "button"
$.ajax({
type: "POST",
url: myUrl,
data: myData,
cache: false,
success: function(html)
{
alert($(self).attr('class')); //returns undefined
}
});

How do I reference the calling dom element in a jquery ajax success function?

I'm trying to modify the class of an element if an ajax call based on that element is successful
<script type='text/javascript'>
$("#a.toggle").click(function(e){
$.ajax({
url: '/changeItem.php',
dataType: 'json',
type: 'POST',
success: function(data,text){
if(data.error=='')
{
if($(this).hasClass('class1'))
{
$(this).removeClass('class1');
$(this).addClass('class2');
}
else if($(this).hasClass('class2'))
{
$(this).removeClass('class2');
$(this).addClass('class1');
}
}
else(alert(data.error));
}
});
return false;
});
</script>
<a class="toggle class1" title='toggle-this'>Item</a>
My understanding of the problem is that in the success function this references the ajax object parameters, NOT the calling dom element like it does within other places of the click function. So, how do I reference the calling dom element and check / add / remove classes?
You can just store it in a variable. Example:
$("#a.toggle").click(function(e)
{
var target = $(this);
$.ajax({
url: '/changeItem.php',
dataType: 'json',
type: 'POST',
success: function(data,text)
{
if(data.error=='')
{
if(target.hasClass('class1'))
{
target
.removeClass('class1')
.addClass('class2');
}
else if(target.hasClass('class2'))
{
target
.removeClass('class2')
.addClass('class1');
}
}
else(alert(data.error));
}
});
return false;
});
jQuery passes the target of the event, along with some other information about it, to your handler function. See http://docs.jquery.com/Events_%28Guide%29 for more info about this.
In your code, it'd be referenced like $(e.target).
Better set ajax parameter : context: this. Example:
$.ajax({
url: '/changeItem.php',
dataType: 'json',
type: 'POST',
context: this,
success: function(data,text){
if(data.error=='')
{
if($(this).hasClass('class1'))
{
$(this).removeClass('class1');
$(this).addClass('class2');
}
else if($(this).hasClass('class2'))
{
$(this).removeClass('class2');
$(this).addClass('class1');
}
}
else(alert(data.error));
}
});
I know it's old but you can use the 'e' parameter from the click function.

Categories

Resources