How to create a sequence of messages in Javascript?

3

I have an application made in Node, Express and Socket.oi in which alerts are sent to a certain screen that receives the message through socket.io, in this screen I receive the message, format it in a dialog and screen display which is hidden after 5 seconds. The problem is that if another user sends an alert during these 5 seconds it replaces the message that is being displayed and I want one message to wait for another before it is displayed. I have tried in several ways, playing in an array and creating a routine, TimeOut and SetInterval but neither of these worked. I leave below an example of how the message is displayed ...

    socket.on('novaMsg', function(data) {
     mostrarMsg(data);
    });

 function mostrarMsg(msg){
 var mensagem = "";
 mensagem += '<p>'+msg.titulo+'</p>';
 mensagem += '<p>'+msg.texto+'</p>';
 $("#dialog .content").html(mensagem);
 $("#dialog").modal("show");
 window.setTimeout(function() {
        $("#dialog").modal('hide');
      }, 5000);
}

If anyone has any idea how to create a routine that shows the messages without replacing them, thank you.

    
asked by anonymous 17.12.2018 / 20:51

2 answers

1

You can create an array to queue the received JSONs, and every half-second check with setInterval if there is an item in the array. If it exists, it will display data from the first item and block new display until the modal is closed. When the modal is closed, it will release new view if there are items in the array.

The socket callback will only add items to the array, creating a queue.

The code looks like this:

var msgs = []; // array
var flag = true; // variável de controle

socket.on('novaMsg', function(data) {
   msgs.push(data);
});

function mostrarMsg(msg){

   var mensagem = "";
   mensagem += '<p>'+msg.titulo+'</p>';
   mensagem += '<p>'+msg.texto+'</p>';
   $("#dialog .content").html(mensagem);
   $("#dialog").modal("show");
   window.setTimeout(function() {
      $("#dialog").modal('hide');

      // remove o primeiro item da array
      msgs.shift();

      // libera nova exibição
      flag = true;
   }, 5000);

}

setInterval(function(){

   // verifica se existe o primeiro item na array e
   // se está liberado nova exibição
   if(msgs[0] && flag){
      flag = false;
      mostrarMsg(msgs[0]);
   }
}, 500);

I'll put below an example simulating the socket. Each time you click the New Alert button, a new JSON will be added to the array and the alerts will be displayed in queue only after modal close. If the array is empty, it will not show anything, but as soon as you click the button, the modal will immediately open showing the alert that was added (I put a sequential number in the title to show that each alert is different):

// linhas de exemplo - início

var conta = 0;

$("button").click(function(){
   
   getData(JSON.parse('{"titulo": "título: '+conta+'", "texto": "texto qualquer"}'));
   conta++;

});

function getData(data){
   msgs.push(data);
}

// linhas de exemplo - fim


var msgs = []; // array
var flag = true; // variável de controle

function mostrarMsg(msg){

   var mensagem = "";
   mensagem += '<p>'+msg.titulo+'</p>';
   mensagem += '<p>'+msg.texto+'</p>';
   $("#dialog .content").html(mensagem);
   $("#dialog").modal("show");
   window.setTimeout(function() {
      $("#dialog").modal('hide');
      
      // remove o primeiro item da array
      msgs.shift();
      
      // libera nova exibição
      flag = true;
   }, 5000);

}

setInterval(function(){
   
   // verifica se existe o primeiro item na array e
   // se está liberado nova exibição
   if(msgs[0] && flag){
      flag = false;
      mostrarMsg(msgs[0]);
   }
}, 500);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><scriptsrc="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css">

<button style="z-index: 9999; position: fixed; top: 0; left: 0">Novo alerta</button>
<!-- Modal -->
<div class="modal fade" id="dialog" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="content">
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
      </div>
    </div>
  </div>
</div>
    
18.12.2018 / 14:35
0
socket.on('novaMsg', function(data) {
  mostrarMsg(data);
});

const renderMsg = ({ titulo, texto }) => '
  <div>
    <p>${titulo}</p>
    <p>${texto}</p>
  </div>
'

function mostrarMsg(msg){
  var mensagem = renderMsg(msg);

  // É bom declarar os elementos em váriaveis
  // para que não percorra o DOM novamente
  const $dialog = $("#dialog");
  const $modalContent = $dialog.find(".content");

  // Pega o conteudo da modal
  // e concatena o conteudo da modal com a mensagem que está vindo do servidor
  // Assim são adicionadas mais de uma mensagem no corpo da modal
  modalContent.html(modalContent.html() + mensagem);

  // Mostra a modal
  $dialog.modal("show");

  // Fecha a modal depois de 5 segundos
  window.setTimeout(function() {
    $dialog.modal('hide');
  }, 5000);
}
    
17.12.2018 / 22:14