Consider the following code, if I click 3 links in a row, the last clicked “section” is updated 3 times, the first 2 remane the same. (assuming you click 3 links before the ajax finishes)
<div><span class="show-records">click me</span></div>
<div><span class="show-records">click me</span></div>
<div><span class="show-records">click me</span></div>
$('.show-records').on('click', function(e) {
el = $(this).parent(); // get parent of clicked link
$.ajax({
url: "...",
method: 'POST',
data: $(this).data('data'),
beforeSend: function() {
el.html('<p style="margin-left: 24px;">loading <span class="loading-spinner"></span></p>'); // show a spinner
},
error: function() {
alert("{{ 'unknown error'|trans({}, 'alerts') }}");
}
}).then(function(html) {
el.html(html); // update html with table
});
});
I can only assume it is because my el
variable is being updated with each click, and “then” always uses the latest el
How can I isolate the parent element between each click event?
I have tried using success
& complete
functions inside $.ajax
but this
& $(this)
are no longer the clicked element.
2
Answers
If you make a new reference to el as a constant. It will fix your issue.
const myEl = $(this).parent(); // get parent of clicked link
The problem appears to be simply that the
el
variable was never formally declared anywhere. Using a variable without declaring it should throw an error, and does in “strict mode”, but unless you opt in to that (highly recommended), the JS engine will implicitly declare any undeclared variables in the global scope.Tha can cause all manner of nasty problems, but here the particular problem was simply that the three event handler functions were “sharing” the same
el
variable, and therefore overwriting it in the way you observed.Whereas if you declare it as a local variable instead (this would work just as well with the “old-fashioned”
var
keyword instead, but let’s be modern), withlet el = ...
, this problem goes away.el
is recreated, pointing to the correct element, each time any of the 3 event handlers run, and none can affect the others.[In fact, as pointed out in other comments/answers,
const
is better here thanlet
]