Display a map

Now that we’ve applied the Map interface to an object, let’s write a simple tool to display the map in the console.

To stay as close to the platform as possible, we’ll render the map as an object in JSON format. JSON isn’t particularly friendly to write or read, but it’s built into the platform and supports hierarchical structures, so it’s adequate for demonstration purposes.

Convert a Map to a plain object #

Our first job is to convert the Map to a plain object so that we can pass it to the standard JSON.stringify:

// Resolve a map to an object with string keys and string values.
function plain(map) {
  const result = {};
  // Get each of the values from the map.
  for (const key of map.keys()) {
    const value = map.get(key);
    result[key] = value instanceof Map ? plain(value) : value.toString();
  }
  return result;
}

It may feel counter-productive to do work to wrap an object with a Map — and then immediately convert it back to an object!

But we’ll soon be working with other kinds of maps, so it’s worth tackling the general case now. We’ve still made an important step to separate the underlying representation of some hierarchical data with a tool to display such data.

Dynamically import a JavaScript module #

We could write a tool to statically import a specific map we want to display, but our goal is a utility that can quickly display any map. So let’s have the tool parse a command line argument specifying the file name of a JavaScript module that exports a map.

/* src/map/json.js */

import path from "node:path";
import process from "node:process";
import { pathToFileURL } from "node:url";

async function plain(map) { /* See above */ }

// Get a file name from the command line.
const [node, command, moduleName] = process.argv;
const modulePath = path.resolve(process.cwd(), moduleName);

// On Windows, import paths must be valid file:// URLs.
const moduleUrl = pathToFileURL(modulePath);

// Load the module.
const module = await import(moduleUrl);

// Take the module's default export as a tree.
const tree = module.default;

// Resolve the tree to an in-memory object.
const obj = plain(tree);

// Convert to JSON text and display it.
const json = JSON.stringify(obj, null, 2);
console.log(json);

The tool dynamically imports the indicated JavaScript file and gets its default export, which is expected to be a map. We then use the plain function above to convert the map to an object, then render the JSON for that object to the console.

Display the map in the console #

Use this json utility from inside the src/map directory to display the object.js map we created in the previous step.

$ node json object.js
{
  "post1.md": "This is **post 1**.",
  "post2.md": "This is **post 2**.",
  "post3.md": "This is **post 3**."
}

 

Next: Transform a map »