javascriptnode.jswebsocketsocket.iotwitter-streaming-api

Why is my form is POSTING multiple times and Socket emitting multiple events?


PROBLEM: When the start/stop button is clicked for FIRST time, the stream starts and stops correctly. The second time, when start button is clicked the router.post() is posting TWICE to server. And when STOP button is clicked the socket event emits twice.

From this point, start/stop buttons trigger exponentially multiple post requests (Starting) and socket events (stopping stream). Crashing the code...

Console after starting and stopping second time (multiple post and socket events)

Stoping Stream...
SOCKET DEF: true
Closing stream...
close stream:  false
startz undefined
POST DEF: false
startStream DEF: true
starting stream...
POST / 200 12.608 ms - 4
startz undefined
POST DEF: true
startStream DEF: true
starting stream...

Browser Console (events triggered multiple times): https://i.sstatic.net/ACEvJ.jpg

index.js

module.exports = function(io) {
  let _stream = {};
  let on_stream = false;

 router.post('/', async (req, res) => {
    // console.log("raw obj " + req.body.searchTerm);
    console.log("startz " + req.body.startBtn);
    console.log("POST DEF:", on_stream);

    startStream(req.body.searchTerm);

    res.send(on_stream);
});


io.on('connection', function(socket) {
  console.log('a user connected index outside routerrr');

  // Listen to stop Button being clicked
  socket.on('stopStream', function()  {
    console.log("Stoping Stream...");
    if(on_stream) {
      console.log("SOCKET DEF:", on_stream);
      closeStream();
    }
  });

});

// start stream
function startStream(term) {
  // return new Promise((resolve, reject) => {
    // console.log("TERM _" +term);
    client.stream('statuses/filter', { track: term }, function(stream) {
      _stream = stream;
      on_stream = true;
      console.log("startStream DEF:", on_stream);

      console.log("starting stream...");
      _stream.on('data', function(tweet) {
      console.log(tweet.text + "Streaming");
          // socket.emit('tweet', tweet.text);
      });

      _stream.on('error', function(error) {
        console.log("erorr:: " + error);
          throw error;
      });
    });
}  


function closeStream() {
  console.log('Closing stream...');
  _stream.destroy();
  on_stream = false;
  console.log("close stream: ", on_stream );
}

   return router;
}

script.js

function startSearchForm() {
   $("#startBtn").on('click', function() {

        let form = $("#search-form");
        let query = form.serialize();
        console.log(query);
        $.post('/', query);
   });  
}
function stopSearchForm() {
    $("#stopBtn").on('click', function() {
        let startSearchValue = $("#searchTerm").val("");
        console.log("Stop Stream...");
        socket.emit('stopStream', function(data) {
            console.log("Stream Stop Complete");
        });

        // let form = $("#searchStop-form");
        // let query = form.serialize();
        // console.log(query);
        // $.post('/', query);
   }); 
}

index.pug

  form#search-form(action='javascript:startSearchForm()', method='POST')
    input(type="text" id="searchedTerm" name="searchTerm" placeholder="#hastag" required)
    button(type="submit"  name="startBtn" id="startBtn") Search

  form#searchStop-form(action='javascript:stopSearchForm()', method='POST')
    input(type="text" id="stopSearch" name="stopSearch" value="stopSearch" hidden)
    button(type="submit" id="stopBtn" name="stopBtn") Stop

Solution

  • How about just removing lines $("#startBtn").on('click', function() { and $("#stopBtn").on('click', function() { (and the closing }); for each)? Looks like startSearchForm and stopSearchForm are being called on click already so let them do the work.