0

I'm trying to get new channel names input by the user to 1) show up on the screen in an unordered list and 2) also show up on other users' screens. I tried to closely follow the template that was used to demonstrate a "voting" website where all users would see what other users had submitted. However, I must be missing a step because although it seems like the name is being accepted, it's not showing up in the list or on other users' screens. The JS worked great when it was directly in the HTML (without connection to SocketIO).

The application.py:

@socketio.on("create channel")
def channel(newchannel):
    if newchannel in existingchannels:
        return render_template("error.html", message="That channel already exists.")

    else:
        existingchannels.append(newchannel)
        emit("create new channel", newchannel, broadcast=True)

The JS:

document.addEventListener('DOMContentLoaded', () => {

  // Connect to websocket
  var socket =io.connect(location.protocol + '//' + document.domain + ':' + location.port);

  // Get user's local localStorage
  var my_storage = window.localStorage;

  // When connected, send them back to the room they were in before they left
  socket.on('connect', () => {
    document.querySelector('#new-channel').onsubmit = () => {
      var newchannel = document.querySelector('#ch-name').value;
      socket.emit('create channel', newchannel);
    };
  });


  // When a new channel is created, add to the unordered list
  socket.on('create new channel', newchannel => {
      // create new item for list
      const li = document.createElement('li');
      li.innerHTML = document.querySelector('#ch-name').value;
      // add item to channel list
      document.querySelector('#channels').append(li);
      // Clear input field for channel Name
      document.querySelector('#ch-name').value = '';
      return false;
  });
});

HTML:

<form id="new-channel">
   <label for="channel name">Create a new channel:</label>
   <input type="text" id="ch-name" name="ch-name">
   <button type="submit">Create!</button>
</form>

<h3>Channels</h3>
<ul id="channels">
</ul>

My thinking is this: In JS, I grab the new channel's name (#ch-name) and call it newchannel, which then gets passed via socketIO into application.py, where it's added to existingchannels = [] , is emitted back to JS, where the newchannel is added to the #channels list. Am I missing a step/too many steps/not seeing something obvious here? I considered just having a regular @app.route("/create") where there is no socketIO happening and it just uses request.form.get to grab the name of the channel and sticks it onto existingchannels.

Any ideas are greatly appreciated!

4
  • Why do you want to add a channal with socket? If the user wants to create a channal he probably wants to use it. You can add a form in channals list page to create a new channal and redirect the user to the newly created channal after submitting the new channals name. No need to create a new route for it. – Tat Apr 21 '20 at 13:43
  • P.S. I know it is not a solution but it will postpone encountering the problem. – Tat Apr 21 '20 at 13:55
  • I want to add a channel via socket so that all the users can see the list of channels being updated. If I keep the channels specific to only the user, nobody else could join. – azb1297 Apr 21 '20 at 18:30
  • You can store new channal's name in a list after creating it and send this list too while rendering the channals tamplate. (return render_template("channals.html", channals_list = channals_list)). The users will not see the new channal right away, but will see all the channals that are already created by the time the user enters "channals.html" page. – Tat Apr 22 '20 at 6:42
0

I ended up using the method suggested in the comments - make a global list of existing channels, and when someone adds a new channel, it will appear (not in real-time, unfortunately) but everyone will see it.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .