Ryan D
Ryan D

Reputation: 751

Reloading Ajax function with setTimeout doesnt clear previous timeout first

I am trying to load a chat box when a contact name is clicked. On initial load it displays the inbox. All functionality works ok until I try and click the contact name a second time. It loads the new contacts chat but also displays the original contact chat even though I set clearTimeout().

Here is the JS file -

$(document).ready(function(){ 
    var contactTimeout;
    var inboxTimeout;

   function contact() {
       var fromName = $('#from').val();
       var toName = $("#to").val();
       $(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
       $(".chat-form").fadeIn(100);

       $.ajax('chat/get-chat.php', {
          data: ({ to: toName,from: fromName}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              contactTimeout = setTimeout(contact, 2000);
          } 
      }); 
   }

   function inbox() {
      var user = $('#from').val();
      $.ajax('chat/get-chat-inbox.php', {
          data: ({ user: user}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              inboxTimeout = setTimeout(inbox, 2000);
           }
       }); 
     }


     // Load inbox when chat box is opened
     $(".chat-arrow").click(function(){
         clearTimeout(contactTimeout);
         inbox();
     });

     // Load chat from contact name
     $(".contact-name").click(function() {
         clearTimeout(contactTimeout); // Here I try and kill previous timeout
         clearTimeout(inboxTimeout);
         var contactName = $(this).attr('id');
         $("#to").val(contactName);
         contact();
     });

});

Why would it just add more timeout functions rather than replace them when a new contact name is clicked?

Upvotes: 0

Views: 42

Answers (1)

Ultrazz008
Ultrazz008

Reputation: 1688

First i would suggest you instead of using replace each time, you could easily use .html(data) to put new data in existing content of chat-body.

And explanation is you call your function on ajax success (there's wait time to server respond to your request) and if you click in meanwhile on your another call, you will have two calls instead of one, because you can't clear timer that's not started yet.

Well one of the solutions would be, let timer works only through it's default state, and when you need some fast data, you can call your contact without calling the next timer.

$(document).ready(function(){ 
    var contactTimeout;
    var inboxTimeout;
   
   /* add parameter which will mean will we call timer or not */
   function contact(dotimer) {
       var fromName = $('#from').val();
       var toName = $("#to").val();
       $(".chat-title").replaceWith("<div class='chat-title'>" + toName + "</div>");
       $(".chat-form").fadeIn(100);

       $.ajax('chat/get-chat.php', {
          data: ({ to: toName,from: fromName}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              /* default calling of timer with repeating */
              if (dotimer) { contactTimeout = setTimeout(function(){ contact(true); }, 2000); }
          } 
      }); 
   }

   function inbox() {
      var user = $('#from').val();
      $.ajax('chat/get-chat-inbox.php', {
          data: ({ user: user}),
          type: "POST",
          success: function(data) {
              $(".chat-body").replaceWith("<div class='chat-body'>" + data + "</div>");
              inboxTimeout = setTimeout(inbox, 2000);
           }
       }); 
     }


     // Load inbox when chat box is opened
     $(".chat-arrow").click(function(){
         clearTimeout(contactTimeout);
         inbox();
     });

     // Load chat from contact name
     $(".contact-name").click(function() {
         clearTimeout(inboxTimeout);
         var contactName = $(this).attr('id');
         $("#to").val(contactName);
         /* call function without TIMER, default one will work as it works */
         contact(false);
     });
});

Upvotes: 1

Related Questions