How can I have 2 separate onmessage event handlers run simultaneously?

Issue

I have a webpage with two separate unordered list. After connecting to a websocket, when I send two different messages the live data I get back from the messages only populate the first list, because the onmessage event. I would like data from message 1 to populate list 1 and the data from message 2 to populate list 2 simultaneously.

JavaScript

        function sendMessage1(event) {
            var input = document.getElementById("messageText1")
            ws.send(input.value)
            input.value = ''
            event.preventDefault()
            ws.onmessage = function (event) {
                var parsed = JSON.parse(event.data)
                var messages = document.getElementById('messages1')
                var message = document.createElement('li')
                var content = document.createTextNode(JSON.stringify(parsed['data']))
                message.appendChild(content)
                messages.appendChild(message)
            };
        }

        function sendMessage2(event) {
            var input = document.getElementById("messageText2")
            ws.send(input.value)
            input.value = ''
            event.preventDefault()
            ws.onmessage = function (event) {
                var parsed = JSON.parse(event.data)
                var messages = document.getElementById('messages2')
                var message = document.createElement('li')
                var content = document.createTextNode(JSON.stringify(parsed['data']))
                message.appendChild(content)
                messages.appendChild(message)
            };

HTML

<div class="flex-container">
        <div class="flex-child">
            <form action="" onsubmit="sendMessage1(event)">
                <input type="text" id="messageText1" autocomplete="off" />
                <button>Send</button>
            </form>
            <ul id='messages1'>
                <li>Enter Channel Subscription Above</li>
            </ul>
        </div>
        <div class="flex-child">
            <form action="" onsubmit="sendMessage2(event)">
                <input type="text" id="messageText2" autocomplete="off" />
                <button>Send</button>
            </form>
            <ul id='messages2'>
                <li>Enter Channel Subscription Above</li>
            </ul>
        </div>
    </div>

Solution

As ultimatum gamer noted, when you do that you overwrite the handler. In order to add several listeners in different places you need some other method:

You can add an event listener


ws.addEventListener('message', event => {
                var parsed = JSON.parse(event.data)
                var messages = document.getElementById('messages2')
                var message = document.createElement('li')
                var content = document.createTextNode(JSON.stringify(parsed['data']))
                message.appendChild(content)
                messages.appendChild(message)
            };
// You can add as many as you want!
ws.addEventListener('message', event => {
                var parsed = JSON.parse(event.data)
                var messages = document.getElementById('messages2')
                var message = document.createElement('li')
                var content = document.createTextNode(JSON.stringify(parsed['data']))
                message.appendChild(content)
                messages.appendChild(message)

You can even specify it some potentially useful options

Unrelated to the question, you should wrap the duplicate functionality in its own function, this will save you time: If you change something in one function you need to change it in the other, this will be a headache and a source of annoying bugs.

Also, your code doesn’t do what you think it will do, you need to parse it somehow and call the appropiate function. For example:

  1. Create the message: const message = {id: 'messages2', data: input.value}
  2. send message
  3. receive message ws.addEventListener('message', event =>{})
  4. parse message and call appropiate function:
event => {
    const parsed = JSON.parse(event.data)
    const message = document.createElement('li')
    const content = document.createTextNode(JSON.stringify(parsed['data']))
    message.appendChild(content)
    const messages = document.getElementById(message.id)
    messages.appendChild(message)
};

Answered By – Orión González

Answer Checked By – Senaida (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.