Print the contents of a JavaScript object to the DOM

Reading Time: 2 minutes 🕑

Last updated: May 3, 2022.

Have you ever tried printing the contents of an object literal to the DOM?

It’s harder than you might think!

Appending or writing to the DOM don’t work:

/* Objects cannot be printed directly to the DOM */

const object = {
   name: "Captain Anonymous",
   job: "Web Developer",
   userPrint: function() { `${this.name}` works as a `${this.job}.` }
}

document.body.append(object);
// Prints: [object Object]

document.body.innerHTML = object;
// Writes: [object Object]

document.write = object;
// Writes: [object Object]

You get the picture.

Solutions

JSON.stringify (but only works for data objects)

One option is to use the JSON.stringify() method. This will convert a JavaScript object to a JSON string type.

Sound promising…but there’s a big catch. It works for a pure data object, but not for an object containing functions:

/* Using JSON.stringify() will ignore functions */

const object = {
   name: "Captain Anonymous",
   job: "Web Developer",
   userPrint: function() { `${this.name} works as a ${this.job}.` },
}

result = JSON.stringify(object);
document.body.append(result);
// Writes: {"name":"Captain Anonymous","job":"Web Developer"}

The function is missing because functions are not JSON-able. So, by using JSON.stringify(), the function is lost when converting the object to a string.

To get the functions out as well requires a little more heavy lifting.

A for...in loop prints data and functions

To print both data and functions, you can use a for...in loop. This type of loop returns the object key in the position of prop for each iteration. This can be used to query the object to get each property value.

Now, combine this information in a template string, optionally add \n at the end of the string to create a line break, and write or append the result to the body:

/* A for...in loop prints data and functions */

const object = {
   name: "Captain Anonymous",
   job: "Web Developer",
   userPrint: function() {`${this.name} works as a ${this.job}.`},
}

let output = '';
for (const prop in object) {
  output += `${prop}: ${object[prop]}\n`;
}

Related links