How to create a message sequence in Javascript?

Asked

Viewed 288 times

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 the socket.io, on this screen I receive the message, format it in a dialog and display in full screen that is hidden after 5 seconds. The problem is that if another user sends an alert during those 5 seconds it replaces the message that is being displayed and I want one message to wait for another before it is displayed. I tried several ways, playing in an array and creating a routine, Timeout and Setinterval but not one of these ways worked. I leave below an example of how the message is being 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 messages without replacing them, thank you.

  • And if in 5 seconds 10 messages are sent, is it to show the 10 messages in a row, one after the other every 5 seconds? That is, the tenth message will wait almost 1 minute to be displayed.

  • Yes, usually a message will be sent every 10 minutes, but it can happen 2 or more are sent at the same time.

2 answers

1


You can create an array to row the received JSON, 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 lock new view until the modal is closed. When the modal is closed, it will release a new view if there are items in the array.

Socket callback will only add items in the array, creating a queue.

The code would look 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 will put below an example simulating the socket. Each time you click the button New alert a new JSON will be added to the array and queued alerts will be shown only after the modal closes. If the array is empty, it will not show anything, but once you click the button, the modal will open immediately 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>
<script src="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>

  • 1

    This worked as well as I needed it, thank you. I had tested it before but I was fumbling with the array and setInterval

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);
}
  • This would work in parts but the problem and who my modal on fullscreen was designed for 2 words, one being a terminal name and the other a numerical sequence, to my view this function would accumulate messages in content without a delete routine and would not add another 5 seconds in the following message.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.