Search code examples
javascriptfunctionfetchpolling

Can I get a fetch function to repeat every few seconds


I have a script that uses Fetch to get some values from the sensors on a device, everything works as expected however the values change frequently. I would like the values to update every second, but the only way I have that working now is to add a function that refreshes the browser every second. This is not very elegant.

Is there a way for me to repeat the fetch command in a loop? so that it gets new values every second without having to refresh the browser?

Here is my code:

        <script>
        fetch('http://192.168.1.114/rr_Status?type=3')
            .then(function (response) {
                return response.json();
            })
            .then(function (data) {
                appendDataAsTable(data);
            })            
            .catch(function (err) {
                console.log('error: ' + err);
            });

        function addCell(tr, val) {
            var td = document.createElement('td');

            td.innerHTML = val;

            tr.appendChild(td)
        }

        function addRow(tbl, val_1, val_2) {
            var tr = document.createElement('tr');

            addCell(tr, val_1);
            addCell(tr, '&nbsp;&nbsp;&nbsp');
            addCell(tr, val_2);
            tbl.appendChild(tr)
        }

        function appendDataAsTable(data) {
            tbl = document.getElementById('tbl');

            addRow(tbl, 'Layer Number', data.currentLayer);
            addRow(tbl, 'Fan Speed', data.params.fanPercent[0] + '%');
            addRow(tbl, 'Print Progress', data.fractionPrinted + '%');
            addRow(tbl, 'Current Speed', data.speeds.top + 'mm/s');
            addRow(tbl, 'Hotend Temp', data.temps.current[1] + '°C');
            addRow(tbl, 'Bed Temp', data.temps.current[0] + '°C');
            addRow(tbl, 'Chamber Temp', data.temps.current[2] + '°C');

        }

    </script>
</head>
<body>
    <div>
        <table id="tbl" border="0" cellspacing="5" align="left" style="font-weight:bold"></table>
    </div>
</body>


Solution

  • You can use setInterval function to invoke the request every few seconds.

    Here, when the document is ready, we are setting up an interval to trigger fetchStatus function to be called every 5 seconds.

    function fetchStatus() {
      fetch('http://192.168.1.114/rr_Status?type=3')
        .then(function (response) {
          return response.json();
        })
        .then(function (data) {
          appendDataAsTable(data);
        })
        .catch(function (err) {
          console.log('error: ' + err);
        });
    }
    
    window.addEventListener('load', function () {
      // Your document is loaded.
      var fetchInterval = 5000; // 5 seconds.
    
      // Invoke the request every 5 seconds.
      setInterval(fetchStatus, fetchInterval);
    });
    

    Update: You could make a slight change in your appendDataAsTable to replace instead of appending and it should resolve your duplicate rendering issue.

    function appendDataAsTable(data) {
        tbl = document.getElementById('tbl');
        
        // Overwrite the existing HTML with new content received.
        tbl.innerHTML = '';
    
        addRow(tbl, 'Layer Number', data.currentLayer);
        addRow(tbl, 'Fan Speed', data.params.fanPercent[0] + '%');
        addRow(tbl, 'Print Progress', data.fractionPrinted + '%');
        addRow(tbl, 'Current Speed', data.speeds.top + 'mm/s');
        addRow(tbl, 'Hotend Temp', data.temps.current[1] + '°C');
        addRow(tbl, 'Bed Temp', data.temps.current[0] + '°C');
        addRow(tbl, 'Chamber Temp', data.temps.current[2] + '°C');
    
    }