Home > Back-end >  Why is `.append($(message_element))` only producing `[object Object]` as output?
Why is `.append($(message_element))` only producing `[object Object]` as output?

Time:10-29

I want to show the message from the server in the HTML page, but whenever I write the message, it says [object Object]. The value has been correctly parsed, but the problem seems to be while appending.

let input_message = document.querySelector('#input-message')
let message_body = document.querySelector('.msg_card_body')
let send_message_form = document.getElementById('send-message-form')
let loc = window.location
let wsStart = 'ws://'

if (loc.protocol === 'https') {
  wsStart = 'wss://'
}

let endpoint = wsStart   loc.host   loc.pathname
var socket = new WebSocket(endpoint)

socket.onopen = function(event) {
  console.log('open', event)
  send_message_form.addEventListener('submit', function(event) {
    event.preventDefault()
    
    let message = input_message.value
    let data = {
      'message': message,
    }
    
    data = JSON.stringify(data)
    socket.send(data)
  })
}
socket.onmessage = function(event) {
  console.log('message', event)
  // console.log(typeof(event.data))
  
  let data = JSON.parse(event.data)
  
  // console.log(typeof(data))
  
  let message = data['message']
  
  // console.log(message)
  newMessage(message)
}
socket.onerror = function(event) {
  console.log('error', event)
}
socket.onclose = function(event) {
  console.log('closed', event)
}

function newMessage(message) {
  if ($.trim(message) === '') {
    return false;
  }

  let message_element = `
    <div >
      <div >
        ${message}
        <span >8:55 AM, Today</span>
      </div>
      <div >
        <img src="data:image/jpeg;">
      </div>
    </div>
  `

  // console.log($(message_element))
  message_body.append($(message_element))
  message_body.animate({
    scrollTop: $(document).height()
  }, 100);
  input_message.value = '';
}

It is not adding any style and it’s not passing any given value. It seems it is taking while message_element as an object and displaying that. I tried using insertAdjecentHTML.

CodePudding user response:

You’re confusing the native DOM API’s append with jQuery’s append. Mixing the jQuery API with the native DOM API in code is not recommended for this very reason.

Element.prototype.append accepts Node objects, or strings as its arguments (0 or more).

jQuery.fn.append accepts HTML strings, Element objects, Text objects, Arrays of Nodes, or jQuery objects as its arguments (0 or more).

You were passing a jQuery object to Element.prototype.append. In the WebIDL definition of append, it specifies its arguments to be of the union type (Node or DOMString). An arbitrary jQuery object cannot be converted to a Node, so the only other option is to convert it to a DOMString. This conversion is possible by mapping an ECMAScript value to a WebIDL DOMString, which basically calls ECMAScript’s ToString abstract operation on the object. The stringification of a jQuery object results in the default "[object Object]" string. Strings are then converted to the equivalent Text nodes and eventually inserted into the DOM.

Any of these work:

API Suggestion Explanation
jQuery $(message_body).append(message_element) Passing an HTML string to jQuery.fn.append.
DOM message_body.insertAdjacentHTML("beforeend", message_element) Passing an HTML string to Element’s insertAdjacentHTML
  • Related