0

I am adding multiple alerts dynamically using JS. I want to add a 5 seconds visibility to individual alerts after which the alert should get disappeared. In my following code, timeout setting applies only to the latest alert added, all previous alerts are loosing their timeout settings.

$(document).ready(function () {
        i=0;
        $('button').click(showSuccess);
        
        function showSuccess() {
            i++;
            $("#myAlert").append("<div class='alert alert-success alert-dismissable alteranimation' id='myAlert_"+i+"'> <button type='button' class='close' data-dismiss='alert'  aria-hidden='true'>&times;</button> Success! message sent successfully.</div>");
           
            setTimeout(() => {
                $('#myAlert_'+i).hide();
            }, 3000);
        }
}

I even tried pushing timeouts to an array in hope of preventing them from getting overridden, but nothing worked.

let a= [];
a.push(setTimeout(() => {
    $('#myAlert_'+i).hide();
}, 3000));
ITSagar
  • 673
  • 2
  • 10
  • 29
  • [How to wait 5 seconds with jQuery?](https://stackoverflow.com/questions/1836105/how-to-wait-5-seconds-with-jquery) – Andreas Oct 13 '22 at 12:15

2 Answers2

1

I don't have an explanation about your code, but code below appear to work.

$(document).ready(function () {
        i=0;
        $('button').click(showSuccess);
        
        function showSuccess() {
            i++;
            let dd = $("<div class='alert alert-success alert-dismissable alteranimation' id='myAlert_"+i+"'> <button type='button' class='close' data-dismiss='alert'  aria-hidden='true'>&times;</button> Success! message sent successfully.</div>");
            $("#myAlert").append(dd);
           
            setTimeout(() => {
                $(dd).hide();
            }, 5000);
        }
});
anaconda
  • 1,065
  • 10
  • 20
1

The problem is the reference to i here:

setTimeout(() => {
  $('#myAlert_'+i).hide();
}, 3000);

Each instance of this continues to reference the same i variable, which continues to change. So if you click the button 3 times before the first timeout, i will have the last of the 3 values for all of the timeouts. So the operation still executes 3 times, but all 3 of them target the same ID.

One simple approach would be to wrap this in an IIFE which passes the value of i to a local variable instead:

((j) => setTimeout(() => {
  $('#myAlert_'+j).hide();
}, 3000))(i);

For example:

$(document).ready(function () {
  i=0;
  $('button').click(showSuccess);

  function showSuccess() {
    i++;
    $("#myAlert").append("<div class='alert alert-success alert-dismissable alteranimation' id='myAlert_"+i+"'> <button type='button' class='close' data-dismiss='alert'  aria-hidden='true'>&times;</button> Success! message sent successfully.</div>");

    ((j) => setTimeout(() => {
      $('#myAlert_'+j).hide();
    }, 3000))(i);
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Click</button>
<div id="myAlert"></div>
David
  • 208,112
  • 36
  • 198
  • 279