E
E
Egor Andreev2021-11-04 18:20:44
AJAX
Egor Andreev, 2021-11-04 18:20:44

How to track new entries in the database and display them on the screen without reloading the page?

Hello. I'm trying to write something like a chat. Wrote adding messages to the database, and their output. But the essence of the task is that new messages themselves would be displayed on the screen without reloading the page. This needs to be done through ajax request (by task) I don’t understand how to write logic so that the request tracks the appearance of new records and displays new messages without reloading. At what records can be added by other chat participants.
This is the message output and form markup:

<?php
  $query = $pdo->query('SELECT * FROM `chat`');
  while ($row = $query->fetch(PDO::FETCH_OBJ)){
    echo "<div class='alert alert-info d-flex justify-content-between'><div>$row->message</div><div><em>$row->login</em></div></div>";
  }
  ?>
  <div id="errorBlock" class="error_block alert alert-danger mt-2"></div>
  <form id="chat_form" method="post">
    <label for="message">Ваше сообщение:</label>
    <textarea id="message" type="text" name="message" class="form-control"></textarea>
    <button id="mes_send" class="btn btn-success mt-4" type="button">Отправить!</button>
  </form>


ajax calling code that adds entries to the database:
$('#mes_send').click(function () {
    var message = $('#message').val();

  $.ajax({
    url: 'ajax/chat.php',
    type: 'POST',
    cache: false,
    data: {'message' : message},
    dataType: 'html',
    success: function(data) {
      if(data == 'Готово') {
        $('#mes_send').text('Всё готово');
        $('#errorBlock').hide();
        $('#chat_form').trigger('reset');
        setTimeout(function(){
          $('#mes_send').text('Отправить!');
        }, 900);
      }
      else {
        $('#errorBlock').show();
        $('#errorBlock').text(data);
      }
    }
  })
  })


the addition itself:
$message = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

    $error ='';

    if(strlen($message) <= 3)
      $error ='Введите нормальное сообщение!';

    if ($error !='') {
      echo $error;
      exit();
    }

    require_once '../mysql_connect.php';

    $sql = 'INSERT INTO chat(message, login) VALUES(:message, :login)';
    $query = $pdo->prepare($sql);
    $query->execute(['message' => $message, 'login' => $_COOKIE['login']]);

    echo "Готово";


I may have added too much, but I wanted to show the big picture. It remains to add code that will track the appearance of new records and display them on the screen without reloading. I guessed only to use the setInterval function. I don't understand how to make the request.
setInterval(function() {
  
    $.ajax({
      url: 'ajax/chat_show.php',
      type: 'POST',
      cache: false,
      data: {},
      dataType: 'html',
      success: function(data) {}
    })
    }, 1500);

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
Sergei Makhlenko, 2021-11-04
@poroshok_uhodi

You need to check for new messages by interval.

let lastMessageId = null
let checkNewMessageInterval = setInterval(() => {
    $.ajax({
      url: 'ajax/checkNewMessage.php',
      type: 'POST',
      cache: false,
      data: {last_id: lastMessageId},
      dataType: 'html',
      success: function(response) {
            let lastMessage = response.data[response.data.length - 1]
            lastMessageId = lastMessage.message_id // сохраняем последнее сообщение которое получили
            // .....
      }
    })
   // ...
}, 5000)

At the last update, you can store the ID of the last message, and on the next request, receive messages only with the ID of the last saved one.
DB query:
SELECT * FROM chat WHERE `message_id` > $_POST['last_id']

even better, first check if there are any new messages at all, and if there is, then already receive these messages:
SELECT COUNT(*) FROM chat WHERE `message_id` > $_POST['last_id']

This is a very simple option I described, but in general, the implementation of chat through AJAX is a crooked option. You will constantly have to pull the database to check for new messages, and so on for each user.
The best and correct option is to use websocket. Using websocket, users will receive messages immediately after they are written, in fact, there is no need to pull the database. Since the database will only serve to load the message history,

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question