Welcome Guest, Not a member yet? Register   Sign In
How to capture EventSource messages while process is running?
#1

I hail from here, where David Friend was an absolute help! However, we have encountered a problem that needs more eyes, so here's a new thread.

I have a codeigniter app that takes in user input, uses JS to fetch/POST the input to a controller, which has it processed by a model. The model needs to send progress updates to the user during the process, but it seems like the fetch promise is capturing all the messages before eventsource can get them and won't display them until the process is finished.
Is there a way to stop fetch from hoarding all the eventsource messages? Or maybe catch each one and display them as they come in and not until the process is done?
My index.php
Code:
    <form id="form1">
      <div class="form-group">
        <label>Date From -></label>
        <input type="text" class="form-control" name="date" id="magento-date" placeholder="2019-10-15 06:46:30">
      </div>
      <div class="form-group">
        <label>Date To <-</label>
        <input type="text" class="form-control" name="dateTo" id="magento-date-to" placeholder="2019-10-16 06:46:30">
      </div>

      <button id="submit" type="submit" class="btn btn-default">Submit</button>
    </form>
    <div class="progress progress-striped active">
      <div class="progress-bar" id="progress" style="width:0%"></div>
    </div>
    <div id="message"></div>

    <script>

    document.querySelector("#submit").addEventListener("click", function(event) {
      event.preventDefault();
      const url = <?= "'".base_url('classic/classicFirearmByDate', 'http')."'"; ?>;

      var myHeaders = new Headers();

      const form = new FormData(document.querySelector('#form1'));

      // The parameters we are gonna pass to the fetch function
      let fetchData = {
          method: 'POST',
          headers: myHeaders,
          body: new URLSearchParams(form)
      }

      //{method: "POST",header:myHeaders,body:{date:'2020baby'}}
      fetch(url, fetchData, message())
      .then((res) => res.text())
      .then(text => console.log(text))
      .catch((error) => console.log(error));

    }, false);
    function message() {
      var evtSource = new EventSource(<?= "'".base_url('classic/classicFirearmByDate', 'http')."'"; ?> );
      var eventList = document.querySelector('#message');

      evtSource.onopen = function () {
          console.log("Connection to server opened.");
      };

      evtSource.onmessage = function (e) {
          console.log(e);
          var newElement = document.getElementById("message");

          newElement.textContent = "message: " + e.data;
          // eventList.appendChild(newElement);
      };

      evtSource.onerror = function () {
          console.log("EventSource failed.");
      };
    }
    </script>
My controller.php
Code:
<?php
class Classic extends CI_Controller{
    . . .
    public function classicFirearmByDate() {
        $data['title'] = 'Classic Firearms';
        $sandbox = $this->input->post('sandbox');
        . . .
        $date = trim(htmlspecialchars($this->input->post('date')));
        $dateTo = trim(htmlspecialchars($this->input->post('dateTo')));
        $data['body'] = $this->classic_firearms->get_firearm_by_date($date, $dateTo, $sandbox, $this->input->post());
My model.php
Code:
<?php
class Classic_firearms extends CI_Model{
. . .
    public function get_firearm_by_date($date, $dateTo, $sandbox, $test) {
            $this->sessionId = $this->login($sandbox);
            $filter = array('complex_filter' => array(
                    array(
                            'key' => 'updated_at',
                            'value' => array(
                                    'key' => 'from',
                                    'value' => $date//'2019-10-03 09:44:30'//
                            ),
                    ),
                    array(
                            'key' => 'updated_at',
                            'value' => array(
                                    'key' => 'to',
                                    'value' => $dateTo//'2019-10-03 09:46:30'//
                            ),
                    ),
            ));

            $productId = $this->proxy->catalogProductList($this->sessionId, $filter);


            header("Content-Type: text/event-stream");
            header("Cache-Control: no-cache");
            header("Connection: keep-alive");

            if ($productId != null || $productId != [] ) {
                    . . . //Many cURL requests and data conversion
                            echo 'data:  Working on {$product_name} Product!', "\n\n";

                            // flush the output buffer and send echoed messages to the browser
                            flush();

One idea I have is to post the user inputs to one controller, store the values in a variable that the class has access too, and then call the main controller with another fetch that won't catch all the messages. I'll start to implement this now, but is that a good idea? Will it work?
Reply


Messages In This Thread
How to capture EventSource messages while process is running? - by SmokeyCharizard - 02-26-2020, 06:52 PM



Theme © iAndrew 2016 - Forum software by © MyBB